fetch与XHR(ajax,axios)的区别与优势

前言:

在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的特点:

  1. fetch基于promise,支持async/await
  2. fetch体现了关注分离思想,比如发送一个请求,它第一次请求成功只是表明连接成功了,然后第二次再请求才能拿到数据
  3. 同构方便,使用isomorphic-fetch
  4. Fetch API更底层。Fetch API 并不是指仅仅一个 fetch 方法,还包括 Request、 Response、Headers、Body都一系列原生对象。对于传统的XHR而言,你必须使用它的一个实例来发出请求和处理响应。 但是通过Fetch API,我们还能够通过刚才提到的原生对象,明确的配置请求和响应。这些底层的抽象让 Fetch API 比 XHR 更灵活。
  5. 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的缺点:

  1. fetch只对网络错误报错,http状态码错误不报错。我们可以通过response 对象的ok是否是true来判断是否是真正的成功。
  2. fetch不支持abort,无法终止
  3. fetch不支持超时控制,使用setTimeout和Promise.reject实现的超时控制不能阻止请求过程继续在后台运行,造成了流量的浪费
  4. fetch没有原生检测请求进度的方式,XHR可以
  5. 默认情况下fetch不发送cookie,除非手动配置
  6. 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。

Guess you like

Origin blog.csdn.net/qq_38974163/article/details/120084004