Fetch 笔记

本文大部分内容由AI生成,笔记类整合记录;

Fetch API 是现代浏览器提供的一个用于发起网络请求的 JavaScript 接口,它提供了一种更强大、更灵活的方式来处理 HTTP 请求,替代了传统的 XMLHttpRequest (XHR)。

Fetch API 提供了一个全局的 fetch() 方法,该方法返回一个 Promise 对象,用于获取网络资源。它的设计遵循"请求-响应"模型,使得处理异步网络请求更加简洁明了

核心组成部分:Request、Response、Headers

使用示例:

javascript 复制代码
// GET
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('There was a problem with the fetch operation:', error);
  });
​
​
// POST
fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'John Doe',
    age: 30
  })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

高级特性:

  • 取消 Fetch 请求

  • 上传文件

  • 流式处理响应

  • 错误处理

    Fetch 只在网络错误时 reject Promise,HTTP 错误状态 (如 404 或 500) 不会导致 reject。因此需要检查 response.okresponse.status

对比 XML

特性 Fetch API XMLHttpRequest
语法 基于 Promise,更简洁 回调方式,较复杂
流式处理 支持 不支持
请求取消 通过 AbortController 原生支持
响应类型 多种转换方法 需要手动设置
CORS 处理 更简单 较复杂
进度事件 不支持 支持
浏览器支持 现代浏览器 所有浏览器
请求头操作 Headers 对象 直接设置

问题:

1、它是什么时候出来的?

Fetch API 是在2015年正式成为Web标准的,具体时间线如下:

  • 2011年:最初由GitHub团队提出概念
  • 2014年:开始被主流浏览器实现
  • 2015年:正式成为WHATWG标准的一部分
  • 2016年:被纳入W3C标准

2、它为什么出来,有什么优势?

  • 基于Promise的简洁语法

  • 更合理的默认行为

    • 不会将HTTP错误状态(如404/500)视为网络错误(XHR会触发onerror)
    • 自动处理CORS相关头部
    • 更简单的请求/响应抽象
  • 更现代的API设计

  • 流式数据处理能力

  • 更好的头信息管理

  • 更灵活的配置选项

3、它的缺陷

尽管Fetch API有很多优势,但也存在一些限制:

  1. 没有原生进度事件:上传/下载进度需要额外实现
  2. IE完全不支持:必须使用polyfill
  3. 默认不发送/接收cookie:需要显式设置credentials
  4. HTTP错误不会reject:需要手动检查response.ok
  5. 较新的高级功能:如流式处理在某些浏览器支持不完整

4、日常开发中,我们应该如何选择?

在日常前端开发中,选择使用原生 Fetch API 还是 Axios 是一个常见的决策点。下面我将详细分析如何选择,并揭示 Axios 的内部实现技术。

选择标准对比表:

标准 Fetch API Axios
浏览器兼容性 现代浏览器(需polyfill支持IE) 全浏览器支持(包括IE)
语法简洁性 较简洁 更简洁(特别是拦截器、取消等)
功能完整性 基础功能 全面功能(进度、取消、拦截器等)
错误处理 需手动检查HTTP错误 自动处理HTTP错误
请求/响应转换 需手动处理 自动转换JSON数据
超时控制 需结合AbortController实现 内置支持
CSRF防护 需手动实现 内置支持
上传进度 不支持 支持
体积 原生API(0kb) 约4kb(压缩后)

具体选择建议

  1. 推荐使用 Fetch 的场景

    • 开发PWA或需要最小化依赖的项目
    • 只需要基础网络请求功能
    • 目标平台是现代浏览器(或已配置polyfill)
    • 项目对包体积极度敏感
  2. 推荐使用 Axios 的场景

    • 需要支持旧版浏览器(如IE11)
    • 项目需要请求/响应拦截器
    • 需要上传/下载进度跟踪
    • 需要更简洁的错误处理
    • 需要自动JSON转换
    • 项目已使用Axios且无迁移必要
  3. 现代替代方案考虑

    • 如果使用React:可考虑React Query或SWR
    • 如果使用Vue:可考虑VueRequest
    • 如果追求极致轻量:可考虑redaxios(类似Axios API的1kb替代)

5、fetch 为什么需要两次await 才能拿到数据?

Fetch API 设计中使用两次 await 的原因涉及响应处理流程的分阶段特性。

核心原因:分阶段响应处理

Fetch 将 HTTP 请求/响应过程明确分为两个阶段:

  1. 元数据获取阶段(第一个 await),理解为获取Header内容

    • 获取响应状态、头部等元数据
    • 验证响应是否成功(检查 response.ok
  2. 正文内容获取阶段(第二个 await),获取Body内容,次过程是一个异步状态

    • 实际读取响应体内容
    • 将原始数据转换为所需格式(JSON/text/blob 等)

详细流程解析

1. 第一次 await:获取 Response 对象

javascript

ini 复制代码
const response = await fetch(url);

这行代码完成后你得到的是:

  • HTTP 状态码(response.status
  • 响应头(response.headers
  • 响应是否成功的标志(response.ok
  • 一个未读取的响应体流response.body

此时响应体尚未被读取,因为:

  1. 性能优化:避免立即读取可能不需要的大响应体
  2. 灵活性:允许开发者先检查元数据再决定如何处理响应体
2. 第二次 await:获取响应体内容

javascript

ini 复制代码
const data = await response.json();

这个阶段实际完成:

  1. 从网络流中读取原始响应数据
  2. 将数据解析为指定格式(这里是JSON)
  3. 返回解析后的结果

总结:

这样设计的目的:

  • 明确的流程控制:清晰分离元数据和内容处理
  • 性能优化:支持流式处理和延迟加载
  • 灵活性:允许开发者根据响应状态决定处理方式
相关推荐
你的人类朋友13 分钟前
🤔什么时候用BFF架构?
前端·javascript·后端
知识分享小能手30 分钟前
Bootstrap 5学习教程,从入门到精通,Bootstrap 5 表单验证语法知识点及案例代码(34)
前端·javascript·学习·typescript·bootstrap·html·css3
一只小灿灿44 分钟前
前端计算机视觉:使用 OpenCV.js 在浏览器中实现图像处理
前端·opencv·计算机视觉
前端小趴菜051 小时前
react状态管理库 - zustand
前端·react.js·前端框架
Jerry Lau1 小时前
go go go 出发咯 - go web开发入门系列(二) Gin 框架实战指南
前端·golang·gin
我命由我123452 小时前
前端开发问题:SyntaxError: “undefined“ is not valid JSON
开发语言·前端·javascript·vue.js·json·ecmascript·js
0wioiw02 小时前
Flutter基础(前端教程③-跳转)
前端·flutter
Jokerator2 小时前
深入解析JavaScript获取元素宽度的多种方式
javascript·css
落笔画忧愁e2 小时前
扣子Coze纯前端部署多Agents
前端
海天胜景2 小时前
vue3 当前页面方法暴露
前端·javascript·vue.js