javascriptFetchAPI如何使用_它与传统的AJAX有什么区别【教程】

技术百科 紅蓮之龍 发布时间:2026-01-27 浏览:
Fetch API 默认不校验HTTP状态码、不携带Cookie,需手动检查response.ok、设置credentials: 'include',且不支持原生上传进度和取消请求。

Fetch API 是现代 JavaScript 中发起网络请求的首选方式,它比传统 XMLHttpRequest(AJAX)更简洁、更符合 Promise 语义,但默认不带 Cookie、不自动处理 4xx/5xx 状态码——这是最容易出错的地方。

fetch() 基本用法和必须处理的两个陷阱

调用 fetch() 返回 Promise,但这个 Promise 只在网络失败(如断网、DNS 错误)时 reject;HTTP 状态码如 404500 仍会 resolve。同时,默认不会携带 Cookie,需显式设置 credentials 选项。

  • 必须用 response.okresponse.status 手动判断业务成功与否
  • 需要显式调用 response.json()response.text() 等方法读取响应体,且每个只能调用一次
  • 发送带凭证的请求时,务必加 { credentials: 'include' },否则后端收不到 Cookie
fetch('/api/user', { credentials: 'include' })
  .then(res => {
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return res.json();
  })
  .then(data => console.log(data))
  .catch(err => console.error(err));

与 XMLHttpRequest(AJAX)的关键行为差异

不是“Fetch 更先进所以该淘汰 AJAX”,而是二者在错误边界、默认行为、控制粒度上存在实质性分歧。很多老项目迁移失败,是因为直接把 XMLHttpRequest 的写法“翻译”成 fetch,却忽略了这些点:

  • XMLHttpRequestonerror 会捕获网络错误 + HTTP 错误;fetchcatch 只捕获网络错误
  • XMLHttpRequest 默认发送 Cookie(取决于同源策略);fetch 默认 credentials: 'omit'
  • XMLHttpRequest 支持 upload.onprogressfetch 没有原生上传进度支持(需用 ReadableStream 手动拆包)
  • XMLHttpRequest 可同步阻塞(已废弃);fetch 异步且不可退回到同步

常见需求对应写法:POST、JSON、表单、错误重试

实际开发中,很少只发一个裸 GET。不同场景下,fetch 的配置和后续处理逻辑差异明显:

  • POST 提交 JSON:headers 要设 'Content-Type': 'application/json',且 body 必须是字符串(用 JSON.stringify()
  • 提交表单(FormData):不用设 Content-Type,浏览器会自动设置带 boundary 的 multipart 类型
  • 简单重试(如 502/5

    03):可在 catch 里判断错误类型,再递归调用或用 setTimeout 延迟重试
  • 取消请求:原生 fetch 不支持 abort,必须传入 AbortController.signal 并在超时或用户离开页面时调用 abort()
const controller = new AbortController();
fetch('/api/data', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ id: 123 }),
  signal: controller.signal
})
// …

兼容性和 polyfill 注意事项

IE 完全不支持 fetch,Safari 10.1+ 才支持 AbortController。如果项目还需兼容旧环境,不要只引入 whatwg-fetch,它不解决 AbortControllerResponse.clone() 缺失问题。

  • whatwg-fetch 可补全基本 fetch 功能,但不支持 signal 和流式读取
  • 需要 abort 能力时,要么降级为 XMLHttpRequest,要么用 abortcontroller-polyfill + 手动封装 cancel 逻辑
  • Response.body(ReadableStream)在 iOS Safari 16.4 之前无法正常使用,做文件下载或大响应流处理时要检测 response.body?.getReader

真正难的不是写对第一行 fetch(),而是记住它不帮你做状态码校验、不帮你带 Cookie、不帮你报上传进度、也不帮你取消——这些“不做什么”,恰恰是日常 Bug 的主要来源。


# 后端  # safari  # 浏览器  # app  # js  # json  # javascript  # java  # 封装  # ios  # cookie  # include  # ajax 


相关栏目: <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 AI推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 SEO优化<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 技术百科<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 谷歌推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 百度推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 网络营销<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 案例网站<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 精选文章<?muma echo $count; ?>

相关推荐

在线咨询

点击这里给我发消息QQ客服

在线咨询

免费通话

24h咨询:4006964355


如您有问题,可以咨询我们的24H咨询电话!

免费通话

微信扫一扫

微信联系
返回顶部