XHR (XMLHttpRequest) 和 Fetch API 是两种在JavaScript中用来发起HTTP请求的主要技术手段,它们都允许在无需刷新页面的情况下从服务器获取数据或提交数据。
XMLHttpRequest (XHR):
- 历史悠久:XHR 是较早被广泛采用的异步通信技术,自1999年开始出现在部分浏览器中,并在 AJAX 技术兴起时变得流行。
- 基于对象:它基于 XMLHttpRequest 这个内置对象,通过构造函数创建实例,然后调用其方法(如
.open()
,.send()
)来发起请求。 - 回调模式:早期的 XHR 主要使用事件监听和回调函数来处理请求的不同阶段(如
onreadystatechange
事件)。 - 灵活性:XHR 支持同步和异步请求,以及多种请求类型(GET, POST等),并且具有丰富的请求和响应头控制能力。
- 请求取消与超时:XHR 允许设置超时并可以通过
abort()
方法取消正在执行的请求。 - 默认行为:XHR 默认会携带 cookies,可以方便地处理同源策略下的session管理。
Fetch API:
- 现代API:Fetch 是一个相对较新的、基于 Promises 的标准,首次出现在 ES6 中,逐步取代 XHR 成为新一代的 HTTP 请求工具。
- Promise 基础:Fetch 返回一个 Promise,这使得异步编程更为简洁,易于理解和实现链式调用和错误处理。
- 语法简洁:Fetch 的语法比 XHR 更加简洁,只需一条语句即可发起请求。
- Request/Response 对象:Fetch 使用
Request
和Response
对象封装请求和响应,提供了更好的结构化处理方式。 - 默认行为变化:Fetch 默认情况下不会自动带上 cookies,除非明确设置了
credentials: 'include'
选项。 - 错误处理:Fetch 对网络错误进行了捕获,但对于非200范围的状态码并不会抛出错误,需要开发者自行检查
Response.ok
或Response.status
来处理非成功状态。 - 缺乏原生特性:Fetch API 相比 XHR 缺乏一些原生支持的功能,例如:
- 不支持原生的请求取消(AbortController后来添加了该功能支持)。
- 不直接支持超时控制(需要配合其他技术如
AbortController
实现)。 - 没有原生的请求进度跟踪(需要监听
ReadableStream
实现)。
Fetch 提供了一个更符合现代 JavaScript 风格的接口,但在某些方面可能需要额外的代码才能达到 XHR 的同等功能。开发者应当根据项目需求和兼容性要求选择合适的请求技术。随着浏览器对 Fetch API 的支持越来越完善,越来越多的新项目倾向于采用 Fetch。