分为以下几个部分,由浅入深:

- 核心基础:
fetchAPI - 现代、强大、推荐使用的网络请求方式。 - 经典方案:
XMLHttpRequest(XHR) - 老牌方案,理解它有助于阅读旧代码。 - 现代应用:WebSocket - 实现全双工、低延迟的实时通信。
- 高级应用:Server-Sent Events (SSE) - 服务器向客户端单向推送数据。
- 最佳实践与常见问题 - 包括错误处理、跨域、安全等。
核心基础:fetch API
fetch 是现代浏览器提供的、基于 Promise 的网络请求 API,是替代 XMLHttpRequest 的首选,它语法更简洁,功能更强大。
基本语法
fetch(url, options) 返回一个 Promise,该 Promise 解析为一个 Response 对象。
// GET 请求示例
fetch('https://api.example.com/data')
.then(response => {
// response 对象包含响应头、状态码等,但响应体本身需要进一步解析
// 首先检查是否成功 (HTTP 状态码 200-299)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// 将响应体解析为 JSON
return response.json(); // response.json() 也是一个 Promise
})
.then(data => {
console.log('获取到的数据:', data);
// 在这里处理数据
})
.catch(error => {
// 捕获网络错误或上面的 throw new Error
console.error('请求失败:', error);
});
POST 请求示例
POST 请求需要在 options 对象中指定 method、headers 和 body。
const postData = {
name: 'John Doe',
email: 'john.doe@example.com'
};
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json', // 告诉服务器我们发送的是 JSON
},
body: JSON.stringify(postData) // 将 JavaScript 对象转换为 JSON 字符串
})
.then(response => response.json())
.then(data => {
console.log('服务器响应:', data);
})
.catch(error => {
console.error('请求失败:', error);
});
fetch 的优点:

- 基于 Promise,避免了回调地狱。
- 语法更简洁、更现代化。
- 提供了对请求和响应流的更好控制。
经典方案:XMLHttpRequest (XHR)
XMLHttpRequest 是一个老牌的 API,在 fetch 出现之前是进行异步网络请求的唯一标准,现在很多旧项目仍在使用它。
基本用法
它通过创建一个 XMLHttpRequest 对象,然后配置和发送请求。
// 1. 创建 XHR 对象
const xhr = new XMLHttpRequest();
// 2. 配置请求
// method: GET/POST/PUT/DELETE
// url: 请求的地址
// true: 表示异步请求
xhr.open('GET', 'https://api.example.com/data', true);
// 3. 设置回调函数
// 当请求状态发生变化时触发
xhr.onreadystatechange = function() {
// readyState 4 表示请求已完成
// status 200 表示请求成功
if (xhr.readyState === 4 && xhr.status === 200) {
// responseText 是服务器返回的原始文本
console.log('获取到的数据:', xhr.responseText);
// 通常需要手动解析 JSON
const data = JSON.parse(xhr.responseText);
console.log('解析后的数据:', data);
} else if (xhr.readyState === 4) {
// 请求完成但失败了
console.error('请求失败,状态码:', xhr.status);
}
};
// 4. 发送请求
// 对于 GET 请求,send() 为空或 null
// 对于 POST 请求,send() 里面放请求体
xhr.send();
XMLHttpRequest 的缺点:
- 基于回调,容易形成回调地狱。
- 语法相对繁琐。
- 不如
fetch灵活。
现代应用:WebSocket
fetch 和 XHR 都是 HTTP 协议的请求-响应模式(客户端问,服务器答),而 WebSocket 是一种全双工通信协议,允许服务器和客户端之间建立一个持久连接,实现服务器主动向客户端推送数据,非常适合实时场景(如聊天室、在线游戏、股票行情等)。

基本用法
// 1. 创建 WebSocket 连接
// ws:// 是 WebSocket 协议,wss:// 是加密的 WebSocket 协议
const socket = new WebSocket('wss://echo.websocket.org'); // 这是一个测试服务器,会回显你发送的消息
// 2. 监听事件
socket.onopen = function(event) {
console.log('WebSocket 连接已建立!');
// 连接成功后,可以发送数据
socket.send('Hello, Server!');
};
socket.onmessage = function(event) {
// event.data 是服务器发来的数据
console.log('收到服务器消息:', event.data);
};
socket.onclose = function(event) {
if (event.wasClean) {
console.log(`连接正常关闭,代码=${event.code} 原因=${event.reason}`);
} else {
// 服务器进程被杀死或网络中断
console.error('连接异常关闭');
}
};
socket.onerror = function(error) {
console.error('WebSocket 发生错误:', error);
};
// 3. 手动关闭连接
// socket.close();
高级应用:Server-Sent Events (SSE)
SSE 是一种服务器向客户端单向推送数据的技术,它基于 HTTP 协议,比 WebSocket 更简单,适用于服务器向客户端实时更新场景(如新闻推送、日志更新)。
客户端使用 EventSource 对象来接收服务器事件。
客户端代码
// 1. 创建 EventSource 对象
// URL 必须支持 CORS
const eventSource = new EventSource('https://api.example.com/updates');
// 2. 监听消息
eventSource.onmessage = function(event) {
// event.data 是服务器推送的数据
console.log('收到更新:', event.data);
};
// 3. 监听自定义事件
// 服务器可以发送不同类型的事件,客户端可以分别监听
eventSource.addEventListener('news', function(event) {
console.log('新闻更新:', event.data);
});
eventSource.addEventListener('like', function(event) {
console.log('收到点赞:', event.data);
});
// 4. 监听错误
eventSource.onerror = function(err) {
console.error('SSE 发生错误:', err);
// 连接断开后,浏览器会自动尝试重新连接
// 如果不想重连,可以关闭
// eventSource.close();
};
服务器端代码 (Node.js 示例)
服务器需要设置正确的 Content-Type 头,并持续发送数据。
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url === '/updates') {
res.writeHead(200, {
'Content-Type': 'text/event-stream', // 关键头
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
// 模拟定时推送数据
const intervalId = setInterval(() => {
const data = { time: new Date().toISOString() };
// 格式: data: <内容>\n\n
res.write(`data: ${JSON.stringify(data)}\n\n`);
}, 1000);
// 当客户端断开连接时,清除定时器
req.on('close', () => {
clearInterval(intervalId);
res.end();
});
} else {
res.writeHead(404);
res.end();
}
});
server.listen(3000, () => {
console.log('SSE 服务器运行在 http://localhost:3000');
});
最佳实践与常见问题
错误处理
fetch:catch会捕获网络错误(如断网),但不会捕获 HTTP 状态码错误(如 404, 500),必须检查response.ok或response.status。XHR: 需要检查xhr.status和xhr.readyState。WebSocket: 通过onerror事件处理。
跨域资源共享
出于安全考虑,浏览器会阻止网页向不同源(不同域名、协议或端口)的 API 发起请求,这被称为同源策略。
解决方案是 CORS (Cross-Origin Resource Sharing)。
- 服务器端配置:服务器需要在响应头中添加
Access-Control-Allow-Origin。Access-Control-Allow-Origin: *
