Fetch API 是广义 Ajax 的一部分,非 XMLHttpRequest 替代品;它返回 Promise 但不自动拒绝 4xx/5xx 错误,需手动检查 response.ok;POST 传 JSON 需设 Content-Type 并 JSON.stringify;不支持同步请求、上传进度事件和内置超时,需 AbortController 实现。

Fetch API 不是 Ajax 的替代品,而是浏览器原生提供的、更现代的网络请求接口;它本身属于广义 Ajax(异步 JavaScript 和 XML)技术体系的一部分,只是不再依赖 XMLHttpRequest 对象。
fetch() 基本用法:GET 请求怎么写
最常用场景是发一个 GET 请求获取 JSON 数据。注意:fetch() 返回 Promise,但不会自动拒绝 HTTP 错误状态(如 404、500),这点和 jQuery.ajax() 行为不同。
-
fetch()默认只 reject 网络错误(如断网、DNS 失败),不 reject 4xx/5xx 响应 - 必须手动检查
response.ok或response.status才能处理业务错误 - 响应体需显式调用
response.json()、response.text()等方法读取,且只能读一次
fetch('/api/users')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
return response.json();
})
.then(data => console.log(data))
.catch(err => console.error('Fetch failed:', err));
POST 请求传 JSON 数据要注意什么
发送 JSON 时,必须同时设置 Content-Type 请求头,并把 JS 对象转成字符串;否则后端很可能收不到或解析失败。
-
body必须是字符串、FormData、Blob等可序列化类型,不能直接传对象 -
headers是普通对象,不是Headers实例(除非你主动 new) - 默认不带 cookie,跨域时需加
credentials: 'include'
fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username: 'admin', password: '123' })
})
.then(r => r.json())
.catch(e => console.error(e));
fetch 和 XMLHttpRequest 最关键的三个区别
不是“谁更好”,而是设计哲学和默认行为不同。老项目迁移到 fetch 时,这几个点最容易出问题:
立即学习“Java免费学习笔记(深入)”;
-
XMLHttpRequest支持同步请求(async: false),fetch()**完全不支持**,只能异步 -
fetch()没有内置上传进度事件(upload.onprogress),要监听上传得用FormData+ 后端配合流式处理,或回退到XMLHttpRequest -
fetch()的重定向行为默认是自动跟随(redirect: 'follow'),而XMLHttpRequest不会自动跳转,302 后需要手动处理 Location
实际开发中建议补什么
原生 fetch() 太简陋,生产环境几乎总会封装一层。至少补上三件事:
- 统一错误处理逻辑(HTTP 状态码 + 网络异常 + JSON 解析失败)
- 自动添加鉴权 token(比如从 localStorage 读
auth_token放进Authorizationheader) - 超时控制——
fetch()本身不支持 timeout,得用AbortController配合
const controller = new AbortController();
setTimeout(() => controller.abort(), 8000);
fetch('/api/data', { signal: controller.signal })
.catch(err => {
if (err.name === 'AbortError') {
console.error('Request timed out');
}
});
真正麻烦的不是语法,而是每个项目都要重新决定:要不要重试?错误弹窗怎么统一?loading 状态怎么透出?这些都得自己搭,没有 $.ajaxSetup() 那种全局钩子。










