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. 返回解析后的结果

总结:

这样设计的目的:

  • 明确的流程控制:清晰分离元数据和内容处理
  • 性能优化:支持流式处理和延迟加载
  • 灵活性:允许开发者根据响应状态决定处理方式
相关推荐
Mr.Jessy12 小时前
JavaScript高级:构造函数与原型
开发语言·前端·javascript·学习·ecmascript
白兰地空瓶14 小时前
🚀你以为你在写 React?其实你在“搭一套前端操作系统”
前端·react.js
爱上妖精的尾巴15 小时前
6-4 WPS JS宏 不重复随机取值应用
开发语言·前端·javascript
似水流年QC15 小时前
深入探索 WebHID:Web 标准下的硬件交互实现
前端·交互·webhid
陪我去看海16 小时前
测试 mcp
前端
speedoooo16 小时前
在现有App里嵌入一个AI协作者
前端·ui·小程序·前端框架·web app
全栈胖叔叔-瓜州16 小时前
关于llamasharp 大模型多轮对话,模型对话无法终止,或者输出角色标识User:,或者System等角色标识问题。
前端·人工智能
三七吃山漆17 小时前
攻防世界——wife_wife
前端·javascript·web安全·网络安全·ctf
用户479492835691517 小时前
面试官问"try-catch影响性能吗",我用数据打脸
前端·javascript·面试
GISer_Jing17 小时前
前端营销技术实战:数据+AI实战指南
前端·javascript·人工智能