前言:
官方推荐是网络请求Fetch 今天记录下这个Fetch
片段一:不同
Ajax JQuery-Ajax axios fetch区别:
传统 Ajax 指的是 XMLHttpRequest(XHR)最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象
JQuery-Ajax 是对原生XHR的封装,除此以外还增添了对JSONP的支持
axios 从浏览器中创建XMLHttpRequest 从node层发起http请求 支持 Promise API
自动转json 客户端支持防止CSRF(因为从cookie里面获取key值后发送到服务端会检测).提供了一些并发请求的接口
Fetch 是基于promise设计的 脱离了XHR
符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里 .更好更方便的写法
片段二:缺点
fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致
请求不能完成时才会被 reject。
fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: 'include'})
fetch没有办法原生监测请求的进度,而XHR可以
片段三:真实的fetch
fetch 是一个 low-level 的 API,它注定不会像你习惯的 $.ajax 或是 axios 等库帮你封装各种各样的功能或实现。
也正是因为这个定位,在学习或使用 fetch API 时,你会遇到不少的挫折。
片段四:请求比你想象的要复杂
这是我对fetch的第一眼认识:
fetch('http://abc.com/tiger.png');
默认是get方法的form-data(也就是headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'})
原来需要 new XMLHttpRequest 等小十行代码才能实现的功能如今一行代码就能搞定,着实让人心动!
很可能会得到一个 401 Unauthorized 的结果,为什么?
会发现原来 fetch 在发送请求时默认不会带上 Cookie!
你需要:
fetch('/api/add?name=lucy', {
credentials: 'include',
...
});
理,如果你需要 POST 一个 JSON 到服务端,你需要这样做:
fetch('/api/add', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
body: JSON.stringify({name: 'lucy'})
});
片段五 错误处理,比你想象的复杂
按照 MDN 的说法,fetch 只有在遇到网络错误的时候才会 reject 这个 promise,比如用户断网或请求地址的域名无法解析等。
所以只要服务器能够返回 HTTP 响应(甚至只是 CORS preflight 的 OPTIONS 响应),promise 一定是 resolved 的状态。
你的404,513,502等一律通过。这个就尴尬了。
判断一个 fetch 请求是不是成功呢?你得用 response.ok 这个字段。
fetch('xx.png')
.then((response) => {
if (response.ok) {
console.log('ok');
} else {
thorw new error('network error');
}
})
.catch(() => {
console.log('error');
});
对数据格式处理
fetch('/api/user.json?id=2') // 服务端返回 {"name": "test", "age": 1} 字符串
.then((response) => {
// 这里拿到的 response 并不是一个 {name: 'test', age: 1} 对象
return response.json(); // 将 response.body 通过 JSON.parse 转换为 JS 对象
})
.then(data => {
console.log(data); // {name: 'test', age: 1}
});
啰嗦一句:
fetch 不支持同步请求 fetch不支持取消一个请求(使用 XMLHttpRequest 你可以用
xhr.abort()
方法取消一个请求) fetch 无法查看请求的进度(使用 XMLHttpRequest 你可以通过
xhr.onprogress
回调来动态更新请求的进度)