JavaScriptfetchAPI简介与使用方法
时间:2025-07-30 19:45:30 111浏览 收藏
JavaScript Fetch API 是现代 Web 开发中发起网络请求的利器。它以 Promise 为基础,简化了异步操作,替代了传统的 XMLHttpRequest。Fetch API 支持 GET、POST 等多种 HTTP 方法,并提供更直观的错误处理机制,区分网络错误与 HTTP 错误。通过 AbortController,开发者可以轻松实现请求取消或超时控制。此外,Fetch API 还具备丰富的配置选项,如自定义 Headers、跨域模式、凭证控制、缓存策略等,赋予开发者强大的灵活性和控制能力。本文将深入探讨 Fetch API 的基本用法、与 XMLHttpRequest 的区别、错误处理方法,以及高级用法和配置选项,助你掌握这一核心 Web 开发技术。
fetch API 是现代 Web 开发中用于发起网络请求的核心工具。1. 它基于 Promise,简化了异步操作,替代了传统的 XMLHttpRequest;2. 支持多种 HTTP 方法如 GET、POST 及文件上传等;3. 提供更直观的错误处理机制,区分网络错误与 HTTP 错误;4. 通过 AbortController 实现请求取消或超时控制;5. 拥有丰富的配置选项,如自定义 Headers、跨域模式、凭证控制、缓存策略等,使其具备强大的灵活性和控制能力。
JavaScript 的 fetch
API 是现代 Web 开发中用于发起网络请求的核心工具。它提供了一种更强大、更灵活的方式来替代传统的 XMLHttpRequest
,通过基于 Promise 的接口,让异步操作的管理变得直观许多,大大简化了数据获取的流程。你可以用它来发送各种类型的 HTTP 请求,比如获取数据、提交表单、上传文件等等。

解决方案
发起一个网络请求,最基本的就是使用 fetch()
函数。它至少需要一个参数,那就是你想要请求的资源路径。
// 发起一个GET请求 fetch('https://api.example.com/data') .then(response => { // 检查响应是否成功 (HTTP状态码在200-299之间) if (!response.ok) { // 如果不是,抛出一个错误,让后续的.catch捕获 throw new Error(`HTTP error! status: ${response.status}`); } // 解析JSON格式的响应体 return response.json(); }) .then(data => { // 处理获取到的数据 console.log('数据已获取:', data); }) .catch(error => { // 捕获任何网络错误或上面抛出的HTTP错误 console.error('获取数据时发生错误:', error); }); // 发起一个POST请求并发送JSON数据 const postData = { name: '张三', age: 30 }; fetch('https://api.example.com/users', { method: 'POST', // 指定请求方法 headers: { 'Content-Type': 'application/json' // 告诉服务器我们发送的是JSON }, body: JSON.stringify(postData) // 将JavaScript对象转换为JSON字符串 }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); // 或者 response.text() 如果预期是文本 }) .then(data => { console.log('用户创建成功:', data); }) .catch(error => { console.error('创建用户时发生错误:', error); });
fetch
与XMLHttpRequest
有什么不同?为什么我应该选择fetch
?
说实话,我刚接触 fetch
的时候,第一感觉就是“这玩意儿比 XMLHttpRequest
(XHR) 简洁太多了”。以前用 XHR,你需要手动监听各种事件(onload
、onerror
、onprogress
),处理状态码,而且回调嵌套多了,代码就变得特别难以维护,就是所谓的“回调地狱”。那种感觉,就像你在一个迷宫里找出口,每一步都得小心翼翼地挂上钩子,生怕哪个环节断了。

fetch
彻底改变了这一切。它基于 Promise,这意味着你可以使用 .then()
和 .catch()
来链式处理异步操作,代码读起来就像同步代码一样,逻辑清晰得多。一个 fetch
请求会返回一个 Promise,这个 Promise 解析为一个 Response
对象。这个 Response
对象非常强大,它包含了响应的所有信息,比如 status
(HTTP状态码)、ok
(一个布尔值,表示状态码是否在 200-299 之间)、headers
等等。最方便的是,它提供了 json()
、text()
、blob()
等方法来异步解析响应体,这些方法本身也返回 Promise,进一步简化了数据处理。
我个人觉得,选择 fetch
的理由主要有几点:

- 现代化和简洁:代码量明显减少,可读性大幅提升。
- Promise 原生支持:与
async/await
语法结合,异步代码写起来几乎和同步代码一样顺滑,大大提升开发效率和代码可维护性。 - 更强大的 API:
Request
和Response
对象提供了更细致的控制和信息访问能力。例如,你可以轻松地检查响应头、处理不同类型的数据流。 - 流式处理能力:
fetch
可以处理响应流,这对于处理大文件下载或实时数据流非常有用,虽然日常开发中可能不常用,但关键时刻能派上大用场。
所以,除非你需要支持一些非常老的浏览器(fetch
在 IE 浏览器上需要 Polyfill),否则 fetch
几乎是现代 Web 开发中发起网络请求的首选。它让网络请求这个曾经的痛点,变得没那么让人头疼了。
如何处理fetch
请求中的错误和异常?
处理 fetch
请求中的错误,说起来有点意思,因为它不像 XMLHttpRequest
那样,只要 HTTP 状态码不是 2xx 就直接进 onerror
。fetch
的 Promise 在遇到网络错误(比如断网、DNS解析失败)时才会 reject
。但如果服务器返回了 4xx 或 5xx 这样的 HTTP 错误状态码,fetch
的 Promise 依然会成功解析(resolve
),只不过 Response
对象的 ok
属性会是 false
。这刚开始可能会让人有点困惑,因为你可能会期待所有非成功的响应都直接进 .catch()
。
所以,正确的错误处理姿势通常是这样的:
网络错误:使用
.catch()
捕获。这是处理真正网络中断、请求无法发送或接收的情况。fetch('/api/nonexistent-endpoint') // 假设这个端点不存在,会是网络错误或跨域问题 .then(response => response.json()) .catch(error => { console.error('网络请求失败:', error); // 比如 TypeError: Failed to fetch });
HTTP 错误(4xx, 5xx):在
.then()
链中检查response.ok
属性。如果response.ok
为false
,你就应该手动抛出一个错误。fetch('/api/unauthorized') // 假设返回401 Unauthorized .then(response => { if (!response.ok) { // 抛出带有状态码和文本的错误 return response.text().then(text => { throw new Error(`HTTP 错误! 状态: ${response.status}, 消息: ${text}`); }); } return response.json(); }) .then(data => console.log('数据:', data)) .catch(error => { console.error('处理请求时发生错误:', error); // 捕获到我们自己抛出的错误 });
这里
response.text()
也是一个 Promise,所以需要再.then()
一次来获取错误消息。这确实是fetch
在错误处理上稍微有点“绕”的地方,需要多写一行。请求超时或取消:
fetch
本身没有内置超时机制,但你可以通过AbortController
来实现。这对于用户长时间等待或者页面跳转时取消未完成的请求非常有用。const controller = new AbortController(); const signal = controller.signal; // 设置一个超时定时器 const timeoutId = setTimeout(() => controller.abort(), 5000); // 5秒后取消请求 fetch('/api/long-running-task', { signal }) .then(response => { clearTimeout(timeoutId); // 请求成功,清除定时器 if (!response.ok) { throw new Error(`HTTP 错误! 状态: ${response.status}`); } return response.json(); }) .then(data => console.log('任务完成:', data)) .catch(error => { clearTimeout(timeoutId); // 捕获到错误,也清除定时器 if (error.name === 'AbortError') { console.warn('请求被取消或超时:', error.message); } else { console.error('请求失败:', error); } }); // 可以在需要时手动取消 // controller.abort();
AbortController
抛出的错误name
是AbortError
,你可以根据这个来区分是超时/取消还是其他类型的错误。这种细致的错误处理,能让你的应用在面对各种网络状况时更加健壮。
fetch
API有哪些高级用法和配置选项?
fetch
的强大之处远不止于简单的 GET 和 POST。它的第二个参数是一个 options
对象,里面包含了大量可配置的选项,让你能精细控制请求的方方面面。我这里挑几个我个人觉得特别有用或容易被忽视的:
自定义请求头 (Headers):这是最常用的一个。你可以通过
headers
选项来添加自定义的 HTTP 头,比如认证 token、内容类型等。fetch('/api/protected-data', { headers: { 'Authorization': 'Bearer your_jwt_token', 'X-Custom-Header': 'HelloFetch' } });
你也可以创建一个
Headers
对象来更结构化地管理请求头:const myHeaders = new Headers(); myHeaders.append('Content-Type', 'application/json'); myHeaders.append('Accept', 'application/json'); fetch('/api/users', { method: 'POST', headers: myHeaders, body: JSON.stringify({ name: 'Alice' }) });
跨域请求模式 (mode):这个选项决定了请求的跨域行为。
cors
(默认):允许跨域请求,但受 CORS 策略限制。no-cors
:用于向其他源发出请求,但响应会被浏览器限制,你无法访问响应头或状态码,只能用于发送请求。这主要是为了兼容一些遗留系统,不推荐在常规场景使用。same-origin
:只允许同源请求。fetch('https://another-domain.com/data', { mode: 'cors' });
凭证模式 (credentials):控制是否随请求发送 cookies、HTTP 认证信息等凭证。
omit
(默认):不发送任何凭证。same-origin
:只在同源请求时发送凭证。include
:无论是否跨域,都发送凭证。如果你需要跨域携带 cookies,就必须设置这个。fetch('https://api.example.com/profile', { credentials: 'include' });
缓存控制 (cache):决定请求如何与 HTTP 缓存交互。
default
:遵循浏览器默认的缓存行为。no-store
:不使用缓存,也不将响应存储到缓存。reload
:强制从网络获取新资源,不使用缓存,但会将新响应存储到缓存。no-cache
:在发送请求前,会先验证缓存副本是否过期。force-cache
:强制使用缓存,即使过期也用,除非没有缓存。only-if-cached
:只在缓存中有副本时才使用,否则失败。fetch('/api/data', { cache: 'no-cache' });
发送文件 (FormData):对于文件上传或发送复杂的表单数据,
FormData
对象是你的好帮手。const formData = new FormData(); formData.append('username', 'JohnDoe'); formData.append('profilePic', myFileInput.files[0]); // myFileInput 是 <input type="file"> 元素 fetch('/upload', { method: 'POST', body: formData // fetch 会自动设置 Content-Type 为 multipart/form-data });
这里
fetch
会自动处理Content-Type
头,你不需要手动设置multipart/form-data
。
这些高级选项让 fetch
不仅仅是一个简单的 HTTP 客户端,它能够处理各种复杂的网络场景,让开发者对请求的生命周期和行为有更强的掌控力。虽然刚开始学可能觉得选项有点多,但一旦掌握了,你会发现它们都是解决特定问题的利器。
到这里,我们也就讲完了《JavaScriptfetchAPI简介与使用方法》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
415 收藏
-
118 收藏
-
416 收藏
-
278 收藏
-
216 收藏
-
230 收藏
-
314 收藏
-
468 收藏
-
457 收藏
-
294 收藏
-
105 收藏
-
336 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习