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

总结:

这样设计的目的:

  • 明确的流程控制:清晰分离元数据和内容处理
  • 性能优化:支持流式处理和延迟加载
  • 灵活性:允许开发者根据响应状态决定处理方式
相关推荐
why技术7 小时前
eli5,我觉得这个全网在吹的技能,使用体验真的很一般啊。
前端·人工智能·后端
excel7 小时前
记录升级 nuxt3 到 nuxt4 记录
前端
剑胆琴心静水深流7 小时前
全栈之路6---web集成与呈现
前端·vue.js·spring boot·分布式·spring·前端框架·npm
前端snow7 小时前
ai agent -- Memory汇总
前端
ITresearchGuest8 小时前
AI 焦虑下,前端该何去何从
前端·人工智能
沙盘客8 小时前
AFSIM 示例解读(03)· 六自由度飞行仿真 six_dof(下):机场运作与弹道导弹投送
java·javascript·经验分享
Codiggerworld8 小时前
Chrome DevTools 隐藏神技:这 5 个调试技巧你可能从来没用过
前端·chrome·chrome devtools
旋生万物8 小时前
【终极实战】用Python从零“生成“一个宇宙:螺旋干涉模型的代码实现
开发语言·前端·人工智能·react.js·php·wpf
IT_陈寒9 小时前
被Java的final坑惨了,这些细节你可能也忽略了
前端·人工智能·后端
kyriewen9 小时前
我带着DeepSeek Harness跑了一周真实需求——这份避坑速查表请收好
前端·ai编程·deepseek