Skip to content
On This Page

fetch()

1. 引言

Fetch API 是现代浏览器提供的用于发起网络请求的接口,旨在取代传统的 XMLHttpRequest(XHR)。它基于 Promise 设计,更简洁、强大。下面是其主要优缺点。

2. 优点

  1. 基于 Promise,语法简洁:支持链式调用和 async/await,避免了回调地狱,代码更易读、易维护。

    javascript
    fetch(url)
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(err => console.error(err));
  2. 更细粒度的控制:可配置请求头、请求方法、缓存模式、重定向策略等,比 XHR 更灵活。

  3. 支持流式处理(Stream):响应体可以按流(response.body)读取,适合处理大文件或实时数据,例如视频、音频或文本流。

  4. 与 Service Worker 深度集成:Fetch 是 Service Worker 中拦截和代理网络请求的标准方式,方便实现离线缓存、请求重试等 PWA 功能。

  5. 默认不带 Cookie,更安全:跨域请求默认不会携带凭据(如 Cookie、HTTP Auth),减少 CSRF 风险。需要时可显式设置 credentials: 'include'

  6. 支持 AbortController:可以通过 AbortController 取消正在进行的请求,避免资源浪费。

    javascript
    const controller = new AbortController();
    fetch(url, { signal: controller.signal });
    controller.abort(); // 取消请求

3. 缺点

  1. HTTP 错误状态不会 rejectFetch 只在网络故障或请求被阻止时才 reject,而 404、500 等 HTTP 错误状态会正常 resolve。开发者必须手动检查 response.ok 并抛出异常。

    javascript
    fetch(url).then(res => {
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      return res.json();
    });
  2. 默认不带 Cookie(既是优点也是缺点):对于需要保持会话的请求(如跨域 API),必须显式设置 credentials: 'include',否则不会发送 Cookie。

  3. 不支持请求超时设置:没有内置的 timeout 属性。要模拟超时,需结合 AbortControllersetTimeout 手动实现。

  4. 无法获取上传/下载进度:Fetch 不提供原生的进度事件(如 XHR 的 onprogress)。上传大文件时无法向用户展示进度条。

  5. 兼容性问题:IE 完全不支持,较老的浏览器(如 Chrome 42 以下)需要 polyfill。在 Node.js 环境中默认不可用(需借助 node-fetch 等库)。

  6. 请求无法取消(旧版):早期版本没有 AbortController,取消请求很麻烦。虽然现在已解决,但仍需额外代码。

4. 总结

维度FetchXMLHttpRequest
语法Promise,简洁回调,繁琐
错误处理需手动处理 HTTP 状态自动区分网络与 HTTP 错误
超时控制需自己实现内置 timeout 属性
进度事件有(onprogress
流式响应支持不支持
取消请求支持(AbortController)支持(abort()

适用场景:Fetch 是现代 Web 应用的首选,尤其适合需要清晰异步逻辑、与 Service Worker 配合或处理流的项目。如果兼容旧版 IE 或需要进度、超时等特性,可考虑使用 axios(基于 XHR 封装)或降级使用 XHR。