第16节:HTML5 新增 API(WebSocket / Fetch)
🧩学习目标
- 理解 WebSocket 协议及其在实时通信中的作用
- 掌握使用 fetch API 替代传统的 XMLHttpRequest
- 了解 Headers、Request、Response 接口的使用
- 掌握使用 async/await 处理异步请求的方法
- 理解跨域问题及其解决方案(CORS)
🧠 内容详解
一、WebSocket 协议与实时通信
1.1 概述
WebSocket 是 HTML5 提供的一种全双工通信协议,允许客户端和服务器之间进行实时数据传输。相比传统的 HTTP 请求,WebSocket 更适合需要频繁交互的应用场景。
1.2 创建 WebSocket 连接
const socket = new WebSocket('ws://example.com/socket');
ws://
表示非加密连接,wss://
表示加密连接。
1.3 WebSocket 事件
事件名 | 描述 |
---|---|
open | 当连接建立时触发 |
message | 接收到服务器消息时触发 |
error | 发生错误时触发 |
close | 连接关闭时触发 |
1.4 发送与接收数据
socket.addEventListener('open', () => {
socket.send('Hello Server!');
});
socket.addEventListener('message', (event) => {
console.log('收到消息:', event.data);
});
1.5 关闭连接
socket.close();
二、fetch API 替代 XMLHttpRequest
2.1 概述
fetch()
是现代浏览器提供的网络请求方法,基于 Promise,比 XMLHttpRequest
更简洁易用。
2.2 基本使用
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('请求失败:', error));
2.3 配置选项
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'Alice' })
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应异常');
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('请求失败:', error));
2.4 详细注释
// 使用 Fetch API 发起一个 GET 请求到指定的 URL
// Fetch API 返回一个 Promise,表示异步操作的结果
fetch('https://api.example.com/data')
// 第一个 .then() 处理响应对象
// response 参数是 Response 对象,表示服务器的响应
.then(response => {
// 检查响应状态码是否表示成功(200-299)
if (!response.ok) {
// 如果响应不成功,抛出错误
throw new Error(`HTTP error! status: ${response.status}`);
}
// 调用 .json() 方法将响应体解析为 JSON 格式
// .json() 也返回一个 Promise,因为它是一个异步操作
return response.json();
})
// 第二个 .then() 处理解析后的 JSON 数据
// data 参数是解析后的 JavaScript 对象或数组
.then(data => {
// 将解析后的数据输出到控制台
console.log(data);
})
// .catch() 处理在请求或解析过程中发生的任何错误
// error 参数是捕获到的错误对象
.catch(error => {
// 将错误信息输出到控制台
console.error('请求失败:', error);
});
代码执行流程说明:
- 发起请求:
fetch('https://api.example.com/data')
发起一个 GET 请求到指定的 URL。 - 处理响应:第一个
.then()
接收Response
对象,检查响应状态码,并调用.json()
方法将响应体解析为 JSON。 - 处理数据:第二个
.then()
接收解析后的 JSON 数据,并将其输出到控制台。 - 错误处理:
.catch()
捕获请求或解析过程中发生的任何错误,并将错误信息输出到控制台。
注意事项:
fetch
默认发起的是 GET 请求。如果需要发起其他类型的请求(如 POST、PUT、DELETE),可以通过配置fetch
的第二个参数来实现。response.json()
是一个异步操作,因此它返回一个 Promise,需要使用.then()
来处理解析后的数据。- 使用
response.ok
检查响应状态码是否表示成功,这是一种常见的做法,因为response.ok
在状态码为 200-299 时返回true
。
三、Headers、Request、Response 接口
3.1 Headers
用于构造和操作 HTTP 请求头:
const headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'Bearer token123'
});
常用方法:
append(name, value)
添加头部字段delete(name)
删除头部字段get(name)
获取头部字段值has(name)
判断是否存在某个字段
3.2 Request
用于创建一个请求对象:
const request = new Request('https://api.example.com/data', {
method: 'GET',
headers: headers
});
3.3 Response
表示响应对象,可以通过 .json()
, .text()
, .blob()
等方法解析内容:
fetch(request)
.then(response => {
console.log('状态码:', response.status);
console.log('是否成功:', response.ok);
return response.json();
})
.then(data => console.log(data));
四、使用 async/await 处理异步请求
结合 async/await
可以更优雅地处理异步请求:
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error('请求失败');
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error('请求出错:', error);
}
}
fetchData();
五、跨域问题与 CORS 解决方案
5.1 跨域概述
当请求的协议、域名或端口不一致时,就会发生跨域问题。浏览器出于安全考虑,默认阻止跨域请求。
5.2 CORS(跨域资源共享)
服务器通过设置以下响应头来允许跨域访问:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
5.3 解决方式
- 后端配置 CORS:推荐做法。
- 代理请求:前端请求本地服务器,由服务器转发请求。
- JSONP(仅限 GET):旧技术,已被 CORS 替代。
六、10大高频面试题
以下是针对 HTML5 新增 API(WebSocket / Fetch) 的 10 大高频面试题,涵盖 WebSocket、fetch、Headers、Response、跨域等核心知识点:
✅1. WebSocket 是什么?与 HTTP 有什么区别?
- 答:
- WebSocket 是一种全双工通信协议,允许客户端和服务器之间持续连接并实时传输数据。
- HTTP 是请求-响应模式,每次通信都需要重新建立连接,适合一次请求后断开的场景。
- WebSocket 更适用于聊天室、在线游戏、实时通知等需要低延迟双向通信的场景。
✅2. 如何创建一个 WebSocket 连接?有哪些常用事件?
- 答:
const ws = new WebSocket('ws://example.com');
常用事件:
open
:连接建立时触发message
:收到服务器消息时触发error
:发生错误时触发close
:连接关闭时触发
✅3. fetch 和 XMLHttpRequest 有什么区别?
特性 | fetch | XMLHttpRequest |
---|---|---|
基于 Promise | ✅ 是 | ❌ 否 |
默认不带 Cookie | ✅ | ❌ 需手动设置 |
支持流式处理 | ✅ | ❌ |
更现代简洁 | ✅ 推荐使用 | 已逐渐淘汰 |
✅4. 如何使用 fetch 发起 POST 请求?
- 答:
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'Alice' })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('请求失败:', error));
✅5. Headers 对象的作用是什么?如何创建和操作?
- 答:
Headers
用于构造和管理 HTTP 请求头信息。
const headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'Bearer token123'
});
headers.append('X-Requested-With', 'XMLHttpRequest');
headers.delete('X-Requested-With');
✅6. Response 对象有哪些常用方法?它们分别返回什么类型的数据?
- 答:
response.json()
:将响应内容解析为 JSON 格式response.text()
:将响应内容解析为纯文本response.blob()
:用于下载文件或图片response.arrayBuffer()
:用于处理二进制数据response.formData()
:用于解析表单数据
✅7. async/await 在 fetch 中的应用方式?
- 答:
async function getData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error('请求失败');
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
✅8. 什么是跨域?为什么浏览器会限制跨域请求?
- 答:
- 跨域是指请求的协议、域名、端口任意一项不同。
- 浏览器出于安全考虑(防止 CSRF 等攻击),默认阻止跨域请求,这就是同源策略(Same-Origin Policy)。
✅9. 如何解决跨域问题?CORS 是怎么工作的?
-
答:
- CORS 是一种由服务器设置响应头的方式,告诉浏览器允许哪些来源访问资源。
常见响应头:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST Access-Control-Allow-Headers: Content-Type
- 其他解决方案:
- 使用代理服务器
- JSONP(仅限 GET 请求)
- 浏览器禁用跨域(仅限开发调试)
✅10. fetch 是否携带 Cookie?如果不携带,如何解决?
- 答:
- 默认情况下,
fetch
不会自动携带 Cookie。 - 如果需要携带 Cookie,必须设置
credentials
选项:
- 默认情况下,
fetch('https://api.example.com/data', {
method: 'GET',
credentials: 'include'
});
注意:此时服务器必须正确配置 CORS 并允许凭据(
Access-Control-Allow-Credentials: true
)。
这些问题是前端面试中关于 HTML5 网络交互 API 的常见考察点,老曹建议结合实际项目经验进行理解和练习。
总结
本节介绍了 HTML5 中新增的重要网络交互 API:
- 使用
WebSocket
实现实时通信; - 使用
fetch
替代XMLHttpRequest
进行 HTTP 请求; - 使用
Headers
、Request
、Response
接口构建和处理请求; - 使用
async/await
编写更清晰的异步代码; - 了解并解决跨域问题(CORS)。
这些知识将帮助你构建更具交互性和实时性的 Web 应用程序。