异步网络请求xhr、ajax、fetch与axios对比

1. XMLHttpRequest对象

现代浏览器,最开始与服务器交换数据,都是经过XMLHttpRequest对象。它可使用JSON、XML、HTML和text文本等格式发送和接收数据。javascript

if (window.XMLHttpRequest) { // model browser
  xhr = new XMLHttpRequest()
} else if (window.ActiveXObject) { // IE 6 and older
  xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
xhr.open('POST', url, true)
xhr.send(data)
xhr.onreadystatechange = function () {
  try {
    // 处理响应
    if (xhr.readyState === 4) {
      // 请求正常
      if (xhr.status === 200) {
        // 处理响应
      } else {
        // 请求遇到一些问题,处理异常
      }
    } else {
      // 还处于未准备好的状态
    }
  } catch (e) {
    // 通讯错误的事件中(例如服务器宕机)
    alert('Caught Exception: ' + e.description)
  }
}
复制代码

优势:前端

  • 不从新加载页面的状况下更新网页
  • 在页面已加载后从服务器请求/接收数据
  • 在后台向服务器发送数据。

缺点:java

  • 使用起来也比较繁琐,须要设置不少值。
  • 早期的IE浏览器有本身的实现,这样须要写兼容代码。

2. jQuery ajax

为了更快捷的操做 DOM,而且规避一些浏览器兼容问题,产生了jQuery。它里面的AJAX请求也兼容了各浏览器,能够有简单易用的方法$.get$.post。简单点说,就是对XMLHttpRequest对象的封装。node

$.ajax({
  type: 'POST',
  url: url, 
  data: data,
  dataType: dataType,
  success: function () {},
  error: function () {}
})
复制代码

优势:jquery

  • 对原生XHR的封装,作了兼容处理,简化了使用。
  • 增长了对JSONP的支持,能够简单处理部分跨域。

缺点:ios

  • 若是有多个请求,而且有依赖关系的话,容易造成回调地狱。
  • 自己是针对MVC的编程,不符合如今前端MVVM的浪潮。
  • ajax是jQuery中的一个方法。若是只是要使用ajax却要引入整个jQuery很是的不合理。

3. fetch

Fetch API提供了一个 JavaScript 接口,用于访问和操做HTTP管道的部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。git

fetch 是底层API,代替XHR,能够轻松处理各类格式,非文本化格式。能够很容易的被其余技术使用,例如Service Workers。可是想要很好的使用fetch,须要作一些封装处理。github

fetch('http://example.com/movies.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });
复制代码

优势:跨域的处理ajax

在配置中,添加mode: 'no-cors'就能够跨域了编程

fetch('/users.json', {
    method: 'post', 
    mode: 'no-cors',
    data: {}
}).then(function() { /* handle response */ });
复制代码

缺点:

  • fetch只对网络请求报错,对400500都当作成功的请求,须要封装去处理
  • fetch默认不会带cookie,须要添加配置项。
  • fetch不支持abort,不支持超时控制,使用setTimeoutPromise.reject的实现超时控制并不能阻止请求过程继续在后台运行,形成了流量的浪费。
  • fetch没有办法原生监测请求的进度,而XHR能够。

请注意,fetch规范与jQuery.ajax()主要有三点不一样,牢记:

  • 当接收到一个表明错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即便该 HTTP 响应的状态码是 404500。相反,它会将 Promise 状态标记为 resolve (可是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject
  • fetch() 不会接受跨域 cookies;你也不能使用fetch() 创建起跨域会话。其余网站的Set-Cookie头部字段将会被无视。
  • fetch 不会发送 cookies。除非你使用了credentials的 初始化选项。(自2017年8月25日之后,默认的credentials策略变动为same-origin。Firefox也在61.0b13版本中,对默认值进行修改)

4. axios

axios是一个基于promise的HTTP库,能够用在浏览器和 node.js 中。它本质也是对原生XMLHttpRequest的封装,只不过它是Promise的实现版本,符合最新的ES规范。

这是官方的并发案例:

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(),getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // Both requests are now complete
  }));

复制代码

axios是尤雨溪大神推荐使用的,

优势:

  • 从浏览器中建立XMLHttpRequests
  • 可在 node.js 中使用
  • 支持 Promise API
  • 提供了并发请求的接口
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防护 XSRF

缺点:

  • 只支持现代浏览器.

5. 参考文档

1. XMLHttpRequest

2. jQuery.ajax

3. 使用 Fetch - Web API 接口参考 | MDN

4. axios