美文网首页react native
Ajax, Axios, Fetch区别

Ajax, Axios, Fetch区别

作者: 小鱼的大白话 | 来源:发表于2018-09-12 18:01 被阅读856次

    本文将会根据自己的理解,来阐述Ajax, Axios, Fetch他们之间的区别

    1 、JQuery ajax

    $.ajax({
      type: 'POST',
      url: url,
      data: data,
      dataType: dataType,
      success: function () {},
      error: function () {}
    });
    

    Ajax是对原生XHR的封装,为了达到我们跨越的目的,增添了对JSONP的支持。经过这么多年的更新维护,不得不承认它已经很成熟,能够满足我们的基本需求,但是随着react,vue新一代框架的兴起,以及ES规范的完善,更多API的更新,它逐渐暴露了自己的不足

    • 针对MVC的编程设计,不符合现在前端MVVM的趋势
    • 基于原生的XHR开发,XHR本身的架构不够清晰
    • JQuery较大,单纯使用ajax却要引入整个JQuery非常的不合理
    • 虽然axios不支持jsonp,但是可以通过引入jsonp模块来解决

    2 、Axios

    axios({
        method: 'post',
        url: '/user/12345',
        data: {
            firstName: 'Fred',
            lastName: 'Flintstone'
        }
    })
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    });
    

    Vue2.0之后,自从尤雨溪推荐大家用axios替换JQuery ajax,Axios快速的得到大家的关注。Axios本质就是对原生XHR的封装,增加了Promise的实,符合最新的ES规范,从它的官网上可以看到它有以下几条特性:

    • 从 node.js 创建 http 请求
    • 支持 Promise API
    • 客户端支持防止CSRF(请求中携带cookie)
    • 提供了一些并发请求的接口(重要,方便了很多的操作)

    Axios既提供了并发的封装,体积也较小,也没有下文会提到的fetch的各种问题,当之无愧是现在最应该选用的请求的方式。

    3、 Fetch

    fetch号称是AJAX的替代品,fetch是基于原生的XMLHttpRequest对象来实现数据请求的,同时也是基于Promise实现链式调用的。它的好处在《传统 Ajax 已死,Fetch 永生》中提到有以下几点:

    • 符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里
    • 更好更方便的写法,诸如:
    try {
      let response = await fetch(url);
      let data = await response.json();
      console.log(data);
    } catch(e) {
      console.log("error:", e);
    }
    

    使用 await 后,告别面条式调用,将异步写成同步,身心舒畅。从上图可以看到await 后面可以跟 Promise 对象,表示等待 Promise resolve() 才会继续向下执行,如果 Promise 被 reject() 或抛出异常则会被外面的 try...catch 捕获。

    坦白说,Jquery还是Axios都已经将xhr封装的足够好,使用起来也足够方便,但是Fetch还是得到很多开发者的认可,说明它还是存在很多优势的:

    • 更加底层,提供的API丰富(request, response)
    • 脱离了XHR,是ES规范里新的实现方式
    • 跨域处理(mode为"no-cors")
    fetch('/testPost', {
        method: 'post',
        mode: 'no-cors',
        data: {}
    }).then(function() {});
    

    但是在使用fetch的时候,也会遇到了一些问题:

    • fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理
    • fetch默认不会带cookie,需要添加配置项fetch(url, {credentials: 'include'})
    • fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
    • fetch没有办法原生监测请求的进度,而XHR可以
    • 所有版本的 IE 均不支持原生 Fetch,fetch-ie8 会自动使用 XHR 做 polyfill。但在跨域时有个问题需要处理。IE8, 9 的 XHR 不支持 CORS 跨域,不支持传 Cookie!所以推荐使用 fetch-jsonp

    PS: fetch的具体问题大家可以参考:《fetch没有你想象的那么美》《fetch使用的常见问题及解决方法



    xhr+promise的实现原理如下:
    function Promise(fn) { 
      this.resolveFn = null; 
      this.rejectFn = null; 
      var _this = this; 
      function resolve(data) { 
        var f = _this.resolveFn; 
        f(data);
     }
      function reject(err) { 
        var f = this.rejectFn;
         f(err); 
     } 
      fn(resolve,reject);
    }
    Promise.prototype.then = function (f) { 
      this.resolveFn = f; return this; 
    }; 
    Promise.prototype.catch = function (f) { 
      this.rejectFn = f; return this; 
    }; 
    function ajax(url,suc,fail) { 
      var xhr = new XMLHttpRequest(); 
      xhr.open('GET',url, true); 
      xhr.onreadystatechange = function () { 
        if(xhr.readyState == 4){
          if(xhr.status == 200){ 
            suc(xhr.responseText) 
          } else { 
            console.log(err); 
            fail(xhr.responseText); 
        }
     } 
    };
      xhr.send(null); 
    } 
    function fetch(url) { 
      console.log('fetch start') 
      return new Promise(function (resolve,reject) { 
        ajax(url,function (res) { 
          resolve(res); 
        },function (err) { 
          console.log(err);
          reject(err); 
        }) 
      }) 
    } 
    
    fetch('/test').then(function (res) { 
      console.log(JSON.parse(res)); 
    }).catch (function (err) { 
      console.log(err); 
    }) 
    

    相关文章

      网友评论

        本文标题:Ajax, Axios, Fetch区别

        本文链接:https://www.haomeiwen.com/subject/bvcbgftx.html