什么是Fetch API_JavaScript中如何使用Fetch发送请求

11次阅读

Fetch API 是现代浏览器发起 http 请求的首选方式,基于 promise 且更简洁;但仅网络失败时 reject,404/500 等状态码仍 resolve,需手动检查 res.ok 或 status;超时与取消需配合 AbortController 使用。

什么是Fetch API_JavaScript中如何使用Fetch发送请求

Fetch API 是浏览器原生提供的、用于发起网络请求的现代接口,它比 XMLHttpRequest 更简洁、更基于 Promise,是当前 javaScript 发起 HTTP 请求的首选方式。

fetch() 基本用法和常见错误

调用 fetch() 返回一个 Promise,但要注意:它只在**网络失败(如断网、dns 错误)时 reject**,而 HTTP 状态码如 404、500 仍会 resolve。这是最容易踩坑的地方。

常见错误现象:fetch('/api/user').then(res => console.log(res.status)) 输出 404 却不报错,后续逻辑照常执行,导致数据解析失败或 ui 异常。

  • 必须手动检查 res.ok(等价于 res.status >= 200 && res.status )
  • 不要直接对 fetch() 调用 .catch() 来捕获 4xx/5xx 错误
  • 响应体需显式调用 res.json()res.text() 等方法读取,且每个只能调用一次

GET 和 POST 请求的写法差异

GET 请求通常只需传入 URL 字符串;POST 则必须配置 methodheadersbody,且 body 类型决定后端接收方式。

立即学习Java免费学习笔记(深入)”;

发送 json 数据时,Content-Type 必须设为 'application/json',否则后端可能无法解析;发送表单数据则应使用 FormData 对象,此时浏览器自动设置正确的 Content-Type(含 boundary)。

fetch('/api/login', {   method: 'POST',   headers: { 'Content-Type': 'application/json' },   body: JSON.stringify({ username: 'admin', password: '123' }) })  const form = new FormData(); form.append('file', fileInput.files[0]); fetch('/upload', {   method: 'POST',   body: form // 不要设 headers,让浏览器自动处理 })

如何处理认证和跨域请求

携带 cookie 需显式设置 credentials: 'include',否则默认不发送;同时服务端必须响应 access-Control-Allow-Credentials: true,且 Access-Control-Allow-Origin 不能为通配符 *

Token 认证一般通过 Authorization 请求头传递:

  • headers: { 'Authorization': 'Bearer ' + token }
  • 若使用 credentials: 'include',注意它与 Authorization 头可共存,但某些代理或 CDN 可能过滤该头
  • 开发时遇到 CORS 报错,先确认预检请求(OPTIONS)是否被正确响应,而不是只看主请求

超时和取消请求怎么实现

Fetch 本身不支持超时或取消,需借助 AbortController 实现。它不是模拟取消,而是真正中止底层连接(从 chrome 89+ 开始生效)。

超时逻辑必须在 Promise race 中封装,且 abort() 后仍需处理已 resolve 的响应(避免未 catch 的 promise rejection)。

const controller = new AbortController(); setTimeout(() => controller.abort(), 5000);  fetch('/api/data', { signal: controller.signal })   .then(res => {     if (!res.ok) throw new Error(`HTTP ${res.status}`);     return res.json();   })   .catch(err => {     if (err.name === 'AbortError') {       console.log('请求超时');     } else {       console.error('请求失败:', err);     }   });

多个并发请求共用一个 AbortController 时,调用 abort() 会全部取消——这点容易被忽略,实际项目中建议按业务粒度独立创建控制器。

text=ZqhQzanResources