fetch
fetch 优势:
- 语法简洁,更加语义化
- 基于标准 Promise 实现,支持 async/await
- 更加底层,提供的 API 丰富(request, response)
- 脱离了 XHR,是 ES 规范里新的实现方式
二、fetch 存在问题
fetch 是一个低层次的 API,你可以把它考虑成原生的 XHR,所以使用起来并不是那么舒服,需要进行封装。
- fetch 只对网络请求报错,对 400,500 都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
- fetch 默认不会带 cookie,需要添加配置项: fetch(url, {credentials: ‘include’})
- fetch 不支持 abort,不支持超时控制,使用 setTimeout 及 Promise.reject 的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
- fetch 没有办法原生监测请求的进度,而 XHR 可以
Request 对象
fetch 请求的地址实际上是对需要一个 Request 对象
const req = new Request(url, {});
fetch(req);
Response 对象
服务器返回过来的数据其实是一个 Response 对象
//模拟服务器返回的请求需要使用Response对象,而不能只是一个json
const resp = new Response(
`[
{"id":1, "name":"北京"},
{"id":2, "name":"天津"}
]`,
{
ok: true,
status: 200,
}
);
Headers 对象
config 中的 Header 的一个 json 本质上是一个 Headers 对象,而不是一个普通 json,传入普通 json 能使用是因为,fetch 进行了处理
new Headers({
a: 1,
b: 2,
});
req = new Request(url, {
headers,
});
文件上传
请求方法:POST
请求的表单格式:multipart/form-data
请求体中必须包含一个键值对,键的名称是服务器要求的名称,值是文件数据
注:js 能访问用户上传到 input 的文件数据,不能获取用户的电脑数据
当body里面给一个formData数据,fetch会自动将header的content-type
设置成multipart/form-data
body内传输的FormData也是一个对象,有特定方法去添加数据
const formData = new FormData(); //构建请求体
formData.append('imagefile', inp.files[0]);
const url = 'http://study.yuanjin.tech/api/upload';
const resp = await fetch(url, {
method: 'POST',
body: formData, //自动修改请求头
});
axios
axios 是一个基于 Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生 XHR 的封装,只不过它是 Promise 的实现版本,符合最新的 ES 规范,它本身具有以下特征:
- 从浏览器中创建 XMLHttpRequest
- 支持 Promise API
- 客户端支持防止 CSRF
- 提供了一些并发请求的接口(重要,方便了很多的操作)
- 从 node.js 创建 http 请求
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换 JSON 数据
// axios举例
axios
.get("/user", {
params: {
ID: 12345,
},
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
总结:axios 既提供了并发的封装,也没有 fetch 的各种问题,而且体积也较小,当之无愧现在最应该选用的请求的方式。