Ajax, Axios, Fetch区别

本文将会根据自己的理解,来阐述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区别)