01. Fetch API 基础概念
在现代前端开发中,Fetch API 提供了一种更简洁的方式来发起网络请求,替代传统的 XMLHttpRequest。它基于 Promise,使异步操作更直观、链式处理更清晰,并且在跨平台的浏览器环境中表现一致。本篇文章是关于 JavaScript Fetch API 简介与使用方法:从入门到实战的完整指南,帮助你从概念到实践逐步掌握该 API。
通过 Fetch API,你可以对请求进行细粒度的配置,如 method、headers、body、mode、cache 等等。核心理念是在请求和响应之间建立一个清晰的异步管道,降低回调地狱的风险,并提升错误处理的一致性。
01.1. 什么是 Fetch API
Fetch API 是浏览器端用于网络请求的现代接口。它用 Fetch 发起请求,返回一个 Promise,解析后得到一个 Response 对象。与旧的 XMLHttpRequest 相比,Fetch 的调用语义更接近自然语言:发出请求、等待响应、处理数据。
在实际使用中,你需要关注跨域策略 (CORS)、请求头、以及响应内容的读取方式。理解这些要点有助于避免常见的坑,例如状态码的处理和响应体的解析。
01.2. 基本请求与响应
使用 Fetch 时,最常见的场景是调用 fetch(url, options),其中 options 可以包括 method、headers、body、credentials 等字段。收到的 Response 对象提供 ok、status、headers 等属性,便于做统一的错误分支。
要读取响应体,可以根据需要选择文本、JSON、二进制数据等格式:text、json、blob、arrayBuffer、formData。读取方式的选择直接决定了后续数据处理的简便性。

02. 使用方法:从入门到实战
本章聚焦从零开始使用 Fetch API 的步骤,覆盖浏览器原生实现、常见错误处理、以及如何把请求集成到前端应用的工作流中。从入门到实战的完整路径,帮助你快速建立可维护的网络通信模块。
在实际项目中,GET 请求、POST 请求、以及带有自定义头部信息的场景是最常见的。掌握这些基础后,你就能够实现数据获取、提交表单、以及与后端服务的对接。
02.1. 基本 GET 请求
GET 请求是最常见的用法之一。它不携带请求体,通常用于获取资源。使用示例中可以看到如何处理返回的状态码、解析 JSON 数据,以及对网络错误做统一处理。
需要注意的是,如果服务器返回非 2xx 的状态码,fetch 仍然会把 Promise 解析为成功的响应对象,因此要通过响应的 ok 属性来判断是否成功,并在失败时抛出错误以进入 catch 分支。
02.2. POST 请求与发送 JSON
POST 请求常用于提交数据,例如创建新资源或提交表单。通过设置 headers 来声明内容类型,并使用 JSON.stringify 将对象序列化为文本,之后在服务器端进行解析。
示例中演示了如何构造一个请求体,以及如何读取服务器返回的确认信息。通过合理的 Content-Type、cache、credentials 设置,可以实现更稳健的交互。
02.3. 请求选项详解
除了 method、headers、body之外,Fetch 还支持 mode、cache、redirect、referrer、integrity 等高级选项。了解这些选项有助于在不同网络策略下获得更好的兼容性与性能。
03. 进阶用法:并发、取消、超时、错误处理
在实际应用中,单次请求往往不足以完成数据组装。通过并发请求、取消请求、以及超时控制,可以显著提升用户体验与页面响应性。关键技巧包括使用 AbortController、Promise.race、以及合并结果的模式。
同时,错误处理策略需要覆盖网络错误、服务器返回错误、以及数据格式错误。鲁棒的实现通常会结合重试策略、指数退避、以及必要的回退内容。
03.1. 取消请求与超时
AbortController 提供了对单次请求的取消能力。通过创建控制器并将它的 signal 传给 fetch,可以在需要时中止请求,提升页面响应性。
为了实现超时,可以使用 Promise.race 将 fetch 与一个定时器组合,超过设定时间后抛出超时错误,避免长时间等待无响应的请求。
const controller = new AbortController();
fetch('https://api.example.com/data', { signal: controller.signal }).then(response => {if (!response.ok) throw new Error('Network response was not ok');return response.json();}).then(data => console.log(data)).catch(err => {if (err.name === 'AbortError') {console.log('Fetch aborted');} else {console.error('Fetch error:', err);}});// 2秒超时
const timeout = ms => new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), ms));
Promise.race([fetch('https://api.example.com/data'), timeout(2000)]).then(res => res.json()).then(console.log).catch(console.error);
03.2. 并发请求与聚合结果
使用 Promise.all、Promise.allSettled 等方法,可以让多组请求并行执行并统一聚合结果。并发处理可以显著缩短总请求时间,并让页面数据更快可用。
在写法上,常见模式是使用 async/await 与 Promise.all 的组合:先发起请求列表,然后等待全部完成,再对结果进行整合和渲染。
04. 实战场景:常见 API 调用场景
把 Fetch API 应用到实际页面中时,设计清晰的错误处理、加载指示,以及数据缓存策略,是提升用户体验的关键。实战应用涵盖数据加载、表单交互、以及离线方案的基本实现。
此外,合理的缓存策略和请求卫士的使用,可以在性能和资源利用之间取得平衡,从而让应用在网络波动时也能保持稳定。
04.1. 表单提交与文件上传
在表单提交场景中,Fetch 可以与 FormData 无缝结合,支持文件上传、文本字段的混合提交,以及上传进度的前端提示。以下示例展示了一个简单的文件上传流程。
const form = new FormData();
form.append('file', fileInput.files[0]);
fetch('/upload', { method: 'POST', body: form }).then(r => r.json()).then(console.log);
04.2. 数据获取与缓存策略
数据获取场景下,结合缓存头、ETag、以及本地缓存,可以减少重复网络请求,提升页面的初次渲染速度。离线情况下,结合 service worker 与缓存 API,可以实现基本的离线数据读取。


