在很长一段时间里,浏览器发送 Ajax 请求主要依赖 XMLHttpRequest,也就是大家熟悉的 XHR。
但随着 JavaScript 生态的发展,XHR 的一些问题越来越明显:
- 代码太啰嗦
- 回调层级复杂
- 错误处理麻烦
- 可读性较差
于是浏览器推出了更现代、更简洁的网络请求方案 Fetch API。
XMLHttpRequest 的问题
先看一个传统 Ajax 请求:
var xhr = new XMLHttpRequest();
xhr.open("GET", "/api/user", true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log(xhr.responseText);
}
}
};
xhr.send();
虽然功能没问题,但存在几个明显缺点:
- 状态判断复杂:必须反复判断 readyState 和 status,初学者经常搞混。
- 回调代码较多:所有逻辑都写在 onreadystatechange 里面,代码一多就会非常乱。
- 服务器返回 JSON 时需要手动转换。
JSON.parse(xhr.responseText)
Fetch 的基本写法
主要是基于 Promise 实现,可以链式调用,不用一层又一层地回调,更符合现代 JavaScript 风格。
注意:这是较新的语法,在某些老版本浏览器上可能支持程度不好,如果需要兼容,可以使用 XHR 或者 Axios、jQuery Ajax 等库。
fetch("/api/user")
.then(function (response) { // Response 对象
return response.json();
})
.then(function (data) {
console.log(data);
})
.catch(function (error) { // 异常处理
console.log(error);
});
相比 XMLHttpRequest:
- 代码明显更短
- 结构更清晰
- 更容易阅读
Fetch 也支持提交数据:
fetch("/api/user", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "Tom",
age: 18
})
})
.then(function (response) {
return response.json();
})
.then(function (data) {
console.log(data);
});