Fetch 是现代、简洁的 Promise-based API,但默认不带 Cookie、不自动报 HTTP 错误、无超时和进度监听;XHR 更底层灵活,支持凭证、进度、超时控制;Ajax 是异步通信概念,Fetch 是其现代实现。
JavaScript 与后端 API 交互,最常用的方式是 Fetch API 和基于 XMLHttpRequest(XHR) 的传统 Ajax。两者本质都是发起 HTTP 请求,但设计思路、语法和默认行为有明显差异。
Fetch 是浏览器原生提供的 Promise-based 接口,语法更接近自然语言,比如:
fetch('/api/users', { method: 'GET
' })
.then(res => res.json())
.then(data => console.log(data));
需要注意几个关键点:
res.ok 判断状态码是否在 200–299 范围credentials: 'include'
AbortController 实现)upload.onprogress
Ajax 是 Fetch 出现前的标准方式,虽然写法稍繁琐,但控制粒度更细:
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/login');
xhr.withCredentials = true; // 显式开启 Cookie 发送
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
console.log(JSON.parse(xhr.responseText));
}
};
xhr.send(JSON.stringify({ user: 'a', pass: 'b' }));
它的优势在于:
upload.onprogress、download.onprogress)xhr.abort() 中断请求responseType)、超时(xhr.timeout)等有直接控制新项目推荐优先用 Fetch,配合 async/await 写法清晰,再用封装函数补足缺失能力(如自动处理错误、统一加 Token、超时控制)。例如:
async function apiGet(url) {
const controller = new AbortController();
setTimeout(() => controller.abort(), 8000);
const res = await fetch(url, {
credentials: 'include',
signal: controller.signal
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
如果需要精细控制上传进度、兼容老版本 IE,或维护遗留系统,则继续使用 XHR 或成熟的库(如 Axios —— 它底层可切换 XHR 或 Fetch,同时封装了拦截器、取消、默认配置等)。
“Ajax” 本意是 “异步 JavaScript 和 XML”,指一类技术思想:不刷新页面、异步加载数据。它不是某个具体 API,而是包括 XHR、Fetch、甚至动态 script 标签等所有能实现异步通信的手段。所以严格来说,Fetch 就是 Ajax 的一种现代实现方式,不是和 Ajax 并列的替代品。