Fetch 是 XMLHttpRequest 的现代 Promise 封装,简洁但默认不发 Cookie(需 credentials: 'include')、不视 4xx/5xx 为错误(需检查 response.ok)、无内置超时/中断(需 AbortController)。

Fetch API 是浏览器原生的异步网络请求接口
它不是“比 AJAX 更好”的替代品,而是 XMLHttpRequest(即传统 AJAX 的底层实现)的现代封装。Fetch 提供了更简洁的 Promise 风格 API,语义更清晰,但默认不带 Cookie、不自动拒绝非 2xx 状态码,这些和 jQuery.ajax 或封装过的 Axios 行为有明显差异。
Fetch 默认不发 Cookie,credentials 必须显式设置
这是最常踩的坑:发起跨域请求时,即使后端已配置 Access-Control-Allow-Credentials: true,Fetch 仍不会携带 Cookie,除非手动指定 credentials 选项。
-
credentials: 'omit'(默认)→ 完全不发 Cookie -
credentials: 'same-origin'→ 同源才发,跨域不发 -
credentials: 'include'→ 总是发 Cookie(跨域时后端必须允许)
fetch('/api/user', {
credentials: 'include'
})
Fetch 不把 4xx/5xx 当错误,response.ok 才是判断依据
fetch() 只在网络失败(如断网、DNS 错误、CORS 被拒)时 reject Promise;HTTP 状态码 404、500 等仍会 resolve,并返回一个 Response 对象。必须手动检查 response.ok 或 response.status。
-
response.ok === true等价于status在 200–299 区间 -
response.json()、response.text()等方法也返回 Promise,需链式处理或 await
fetch('/api/data')
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => console.error(err));
没有内置超时和请求中断机制,得自己补
Fetch 本身不支持 timeout 参数,也不像 XMLHttpRequest.abort() 那样能直接取消请求。要实现超时或取消,得靠 AbortController + signal 选项:
立即学习“Java免费学习笔记(深入)”;
- 创建
AbortController实例,传signal给 fetch - 用
setTimeout调用controller.abort() - 捕获
AbortError(注意不是所有浏览器都抛这个错误名)
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
fetch('/api/slow', { signal: controller.signal })
.catch(err => {
if (err.name === 'AbortError') console.log('Request timed out');
});
实际项目中是否“更好”,取决于你是否愿意为更干净的 API 接受这些默认行为差异;很多团队仍用 Axios,就是因为它默认处理了 Cookie、状态码、超时、CSRF token 注入等细节。Fetch 简洁,但“开箱即用”的程度不如封装层。











