Fetch API 是浏览器原生现代网络请求接口,本质是 XMLHttpRequest 的 Promise 化升级;默认不带 Cookie,需显式设置 credentials: 'include';不因 HTTP 错误状态码 reject,须手动检查 response.ok;取消请求需配合 AbortController。

Fetch API 是浏览器原生提供的、用于发起网络请求的现代接口,它不是 AJAX 的替代品,而是对传统 XMLHttpRequest(即常说的 AJAX)的封装升级——本质仍是异步 HTTP 请求,但设计更符合 Promise 语义和现代 JS 开发习惯。
Fetch 默认不带 cookie,而 XMLHttpRequest 默认会携带
这是最常踩坑的一点:用 fetch() 发起跨域请求时,即使服务端已设置 Access-Control-Allow-Credentials: true,默认也不会发送 Cookie 或认证头。
- 必须显式传入
credentials: 'include'选项才能带上 Cookie -
XMLHttpRequest在同域下默认发送 Cookie,跨域时需手动调用xhr.withCredentials = true - 若只读取公开资源(如 CDN 图片、公共 API),可忽略;但涉及登录态、Session 的接口,漏掉这个配置就会 401 或返回未登录状态
fetch('/api/user', {
credentials: 'include'
})
Fetch 不会因 HTTP 状态码异常而 reject,需手动检查 response.ok
fetch() 只在网络失败(如断网、DNS 错误、跨域被拦)时才抛出 Promise reject;404、500 这类响应仍会进入 then(),容易误以为请求“成功”了。
-
response.ok是布尔值,仅当状态码在200–299范围内为true - 常见写法是链式判断:
if (!res.ok) throw new Error(`${res.status}`) -
XMLHttpRequest没有内置这种语义,需开发者自己对比xhr.status
fetch('/api/data')
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => console.error(err));
Fetch 不支持 abort 旧请求(需配合 AbortController)
不像 XMLHttpRequest 可直接调用 xhr.abort() 中断进行中的请求,fetch() 本身无中止方法,必须借助 AbortController 实现超时或取消。
立即学习“Java免费学习笔记(深入)”;
- 创建控制器:
const controller = new AbortController() - 传入
signal选项:fetch(url, { signal: controller.signal }) - 主动取消:
controller.abort(),此时 fetch 会 reject 并抛出AbortError - 注意:不是所有浏览器都支持(IE 完全不支持,Edge 16+ 开始支持)
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
fetch('/api/slow', { signal: controller.signal })
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求超时被取消');
}
});
真正难的不是写对语法,而是理解 fetch 的“静默成功”逻辑、凭空消失的 cookie、以及取消请求时那层额外的信号绑定——这些细节一旦漏掉,调试时往往卡在“明明返回了数据,但后端说没收到 session”的怪圈里。











