js fetch(超详细)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

了解 JavaScript 的现代化网络请求工具:js fetch

在现代 Web 开发中,与服务器进行数据交互是核心需求之一。无论是获取天气信息、加载用户列表,还是提交表单数据,都需要可靠的网络请求工具。js fetch 是 JavaScript 原生提供的现代化 API,它以简洁的语法和灵活的配置选项,成为开发者首选的 HTTP 客户端工具。本文将从基础用法到高级技巧,逐步解析这一工具的原理与实践。


一、为什么选择 js fetch?

js fetch 出现之前,开发者主要依赖 XMLHttpRequest(简称 XHR)或第三方库(如 jQuery 的 $.ajax)来发送网络请求。然而,这些方案存在明显不足:

  • XHR 的语法繁琐:需要手动配置多个属性,代码可读性差;
  • 回调地狱问题:嵌套的回调函数导致代码难以维护;
  • 缺乏统一标准:第三方库的 API 设计差异较大,学习成本高。

js fetch 的诞生彻底改变了这一局面。它基于现代 JavaScript 的 Promise 语法,支持 async/await 语法糖,解决了回调嵌套问题;同时提供统一的 API 设计,简化了 HTTP 请求的配置与响应处理。


二、快速上手:基础用法与核心概念

1. 最简单的 GET 请求

发送 GET 请求是最常见的操作,例如获取公开数据接口的响应:

fetch("https://api.example.com/data")  
  .then(response => {  
    // 处理响应数据  
    console.log("Status:", response.status);  
    return response.json(); // 解析 JSON 格式数据  
  })  
  .then(data => {  
    console.log("Data:", data);  
  })  
  .catch(error => {  
    console.error("Error:", error);  
  });  

关键点解析

  • fetch() 返回一个 Promise,成功时返回 Response 对象,失败时触发 catch
  • response.json() 将响应体解析为 JSON 对象,同样返回 Promise
  • 链式调用.then().then().catch())是处理异步操作的标准方式。

2. 配置选项与 POST 请求

除了 GET 请求,我们常常需要发送 POST 请求以提交数据。例如,向服务器提交表单:

const formData = {  
  username: "user123",  
  email: "user@example.com"  
};  

fetch("https://api.example.com/submit", {  
  method: "POST",  
  headers: {  
    "Content-Type": "application/json"  
  },  
  body: JSON.stringify(formData)  
})  
.then(response => response.json())  
.then(data => console.log("Success:", data))  
.catch(error => console.error("Error:", error));  

配置对象详解
| 属性名 | 作用说明 |
|--------------|--------------------------------------------------------------------------|
| method | 指定 HTTP 方法(如 GET、POST、PUT 等,默认为 GET) |
| headers | 设置请求头,例如指定 Content-Type 或认证信息 |
| body | 发送请求体,需与 Content-Type 匹配(如 JSON 需要 JSON.stringify()) |
| mode | 控制跨域行为,常用值为 cors(默认)或 no-cors |


三、深入理解:响应处理与错误捕获

1. 响应对象的详细解析

fetch 返回的 Response 对象包含丰富的信息:

  • 状态码response.status 返回 HTTP 状态码(如 200 表示成功,404 表示未找到);
  • 响应体:通过 response.text()response.json()response.blob() 解析不同格式的数据;
  • 响应头response.headers.get("Header-Name") 可获取服务器返回的自定义头信息。

2. 错误处理的两种模式

模式一:链式 catch

fetch("https://api.example.com/invalid")  
  .then(response => {  
    if (!response.ok) {  
      throw new Error("HTTP error " + response.status);  
    }  
    return response.json();  
  })  
  .catch(error => console.error("Error:", error));  

模式二:async/await 语法

async function fetchData() {  
  try {  
    const response = await fetch("https://api.example.com/data");  
    if (!response.ok) {  
      throw new Error("HTTP error " + response.status);  
    }  
    const data = await response.json();  
    console.log("Data:", data);  
  } catch (error) {  
    console.error("Error:", error);  
  }  
}  

对比说明

  • 链式 then/catch 需要手动抛出错误(如 response.ok 检查);
  • async/await 语法更接近同步代码结构,但需在 async 函数内使用。

四、进阶技巧:优化与高级场景

1. 使用 FormData 上传文件

当需要上传文件时,FormData 是更自然的选择:

const form = new FormData();  
form.append("username", "user123");  
form.append("avatar", fileInput.files[0]); // fileInput 是 <input type="file">  

fetch("https://api.example.com/upload", {  
  method: "POST",  
  body: form  
})  
.then(response => response.text())  
.then(data => console.log("Upload result:", data));  

优势

  • 自动设置正确的 Content-Type(如 multipart/form-data);
  • 支持大文件传输,无需手动编码。

2. 流式处理大文件

对于大文件下载或实时数据流,可使用 ReadableStream

fetch("https://api.example.com/large-file")  
  .then(response => response.body.pipeThrough(new TextDecoderStream()))  
  .then(stream => {  
    const reader = stream.getReader();  
    return readStream(reader); // 自定义读取逻辑  
  });  

适用场景:实时日志监控、视频流传输等需要逐步处理数据的场景。

3. 跨域问题与 mode 配置

当请求第三方接口时,需确保服务器允许跨域请求(CORS)。若遇到问题,可尝试以下配置:

fetch("https://api.example.com/data", {  
  mode: "cors" // 明确启用跨域请求(默认值)  
});  

注意:服务器需设置 Access-Control-Allow-Origin 响应头,否则请求将失败。


五、性能优化与最佳实践

1. 缓存控制与超时处理

通过 Cache-Control 头或 setTimeout 实现请求超时:

const controller = new AbortController();  
const timeoutId = setTimeout(() => controller.abort(), 3000); // 3秒超时  

fetch("https://api.example.com/data", {  
  signal: controller.signal  
})  
.then(response => {  
  clearTimeout(timeoutId);  
  return response.json();  
})  
.catch(error => {  
  if (error.name === "AbortError") {  
    console.log("Request timed out!");  
  }  
});  

2. 合并多个请求与节流

使用 Promise.all() 同时发送多个请求:

Promise.all([  
  fetch("https://api.example.com/data1"),  
  fetch("https://api.example.com/data2")  
])  
.then(responses => {  
  return Promise.all(responses.map(r => r.json()));  
})  
.then(data => {  
  console.log("All data:", data);  
});  

六、对比与替代方案

尽管 js fetch 功能强大,但某些场景可能需要其他工具:

  • XMLHttpRequest:兼容性更好(支持旧版浏览器),但代码冗长;
  • Axios:基于 fetch 的封装,提供更友好的 API(如 axios.get())和拦截器功能;
  • navigator.sendBeacon():用于发送非关键数据(如日志),确保页面卸载时也能发送。

结论

从基础的 GET/POST 请求到高级的流式处理,js fetch 凭借其简洁的语法和强大的功能,已成为现代 Web 开发的基石。通过合理配置请求头、处理响应流、优化性能,开发者可以高效地构建与服务器交互的复杂应用。无论是初学者还是中级开发者,掌握这一工具都能显著提升开发效率,为构建响应式、流畅的 Web 应用打下坚实基础。

实践建议:尝试用 fetch 实现一个天气查询工具或简单的 REST API 客户端,逐步掌握从配置到错误处理的完整流程。

最新发布