前言:
在Fetch出现之前我们发送异步请求默认都是通过ajax,底层使用了宿主环境的(XHR)XMLHTTPRequest 对象来实现异步请求,包括axios也是使用xhr技术实现的,只是语法基于promise,解决了回调地狱的问题。实现代码如下:
var xhr = new XMLHttpRequest();
xhr.open("get","example.php", true);
xhr.send(null);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status == 200){
alert(xhr.responseText);
}
}
}
当然我们一般会用一些封装过的ajax实现解决传统方式的繁琐写法以及xhr低版本浏览器可能出现的兼容问题,比如jquery的ajax:
$.ajax({
url: 'example.asp',
type: 'get',
success: function(){
}
})
fetch知识
Fetch的特点:
- fetch基于promise,支持async/await
- fetch体现了关注分离思想,比如发送一个请求,它第一次请求成功只是表明连接成功了,然后第二次再请求才能拿到数据
- 同构方便,使用isomorphic-fetch
- Fetch API更底层。Fetch API 并不是指仅仅一个 fetch 方法,还包括 Request、 Response、Headers、Body都一系列原生对象。对于传统的XHR而言,你必须使用它的一个实例来发出请求和处理响应。 但是通过Fetch API,我们还能够通过刚才提到的原生对象,明确的配置请求和响应。这些底层的抽象让 Fetch API 比 XHR 更灵活。
- fetch配置请求是否携带cookie和接受服务端写入cookie是通过设置credentials
// 所有情况都携带cookie
fetch('https://example.com', {
credentials: 'include'
})
// 目前改为默认是same-origin
// 同源的情况下带cookie
fetch('https://example.com', {
credentials: 'same-origin'
})
// 忽略cookie
fetch('https://example.com', {
credentials: 'omit'
})
Fetch的缺点:
- fetch只对网络错误报错,http状态码错误不报错。我们可以通过response 对象的ok是否是true来判断是否是真正的成功。
- fetch不支持abort,无法终止
- fetch不支持超时控制,使用setTimeout和Promise.reject实现的超时控制不能阻止请求过程继续在后台运行,造成了流量的浪费
- fetch没有原生检测请求进度的方式,XHR可以
- 默认情况下fetch不发送cookie,除非手动配置
- fetch是比较新的语法,兼容性不是很好,在使用之前一定要做好兼容探测处理。避免意外出现。
fetch请求示例:
最原始写法
fetch(url).then(
res => {
return res.json()
}
err => {
console.log(err)
return new Promise()
/**不写这句的话,如果这里发生错误了,返回的讲师undefined,
那么下面那个.then就是链式调用一个常量,那么相当于直接执行
成功的回调,并且值为undefined。所以我们可以返回一个新的
promise对象解决这个问题**/
}
).then(
data => {
console.log(data)
}
err => {
console.log(err)
}
)
改进写法:
fetch(url).then(
res => {
return res.json()
}
).then(
data => {
console.log(data)
}
).catch(
err => {
console.log(err)} //用catch统一处理报错
)
再进阶(配合async await):
async fuc (){
try{
const response = await fetch(url)
const data = response.json()
} catch(err) {
console.log(err)
}
}
async await只能等待成功的回调,所以配合try catch捕获错误
Fetch更多参数
fetch(url, {
body: JSON.stringify(data), // must match 'Content-Type' header
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, same-origin, *omit
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
},
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // *client, no-referrer
})
总结
如果以后有面试官问你如果不用xhr,前端还不能发送请求,你就可以坚定的说:当然可以!fetch wlds。