fetch()
1. 引言
Fetch API 是现代浏览器提供的用于发起网络请求的接口,旨在取代传统的 XMLHttpRequest(XHR)。它基于 Promise 设计,更简洁、强大。下面是其主要优缺点。
2. 优点
基于 Promise,语法简洁:支持链式调用和
async/await,避免了回调地狱,代码更易读、易维护。javascriptfetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(err => console.error(err));更细粒度的控制:可配置请求头、请求方法、缓存模式、重定向策略等,比 XHR 更灵活。
支持流式处理(Stream):响应体可以按流(
response.body)读取,适合处理大文件或实时数据,例如视频、音频或文本流。与 Service Worker 深度集成:Fetch 是 Service Worker 中拦截和代理网络请求的标准方式,方便实现离线缓存、请求重试等 PWA 功能。
默认不带 Cookie,更安全:跨域请求默认不会携带凭据(如 Cookie、HTTP Auth),减少 CSRF 风险。需要时可显式设置
credentials: 'include'。支持 AbortController:可以通过
AbortController取消正在进行的请求,避免资源浪费。javascriptconst controller = new AbortController(); fetch(url, { signal: controller.signal }); controller.abort(); // 取消请求
3. 缺点
HTTP 错误状态不会 reject:Fetch 只在网络故障或请求被阻止时才 reject,而 404、500 等 HTTP 错误状态会正常 resolve。开发者必须手动检查
response.ok并抛出异常。javascriptfetch(url).then(res => { if (!res.ok) throw new Error(`HTTP ${res.status}`); return res.json(); });默认不带 Cookie(既是优点也是缺点):对于需要保持会话的请求(如跨域 API),必须显式设置
credentials: 'include',否则不会发送 Cookie。不支持请求超时设置:没有内置的
timeout属性。要模拟超时,需结合AbortController和setTimeout手动实现。无法获取上传/下载进度:Fetch 不提供原生的进度事件(如 XHR 的
onprogress)。上传大文件时无法向用户展示进度条。兼容性问题:IE 完全不支持,较老的浏览器(如 Chrome 42 以下)需要 polyfill。在 Node.js 环境中默认不可用(需借助
node-fetch等库)。请求无法取消(旧版):早期版本没有
AbortController,取消请求很麻烦。虽然现在已解决,但仍需额外代码。
4. 总结
| 维度 | Fetch | XMLHttpRequest |
|---|---|---|
| 语法 | Promise,简洁 | 回调,繁琐 |
| 错误处理 | 需手动处理 HTTP 状态 | 自动区分网络与 HTTP 错误 |
| 超时控制 | 需自己实现 | 内置 timeout 属性 |
| 进度事件 | 无 | 有(onprogress) |
| 流式响应 | 支持 | 不支持 |
| 取消请求 | 支持(AbortController) | 支持(abort()) |
适用场景:Fetch 是现代 Web 应用的首选,尤其适合需要清晰异步逻辑、与 Service Worker 配合或处理流的项目。如果兼容旧版 IE 或需要进度、超时等特性,可考虑使用 axios(基于 XHR 封装)或降级使用 XHR。