異步網絡請求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

相關文章
相關標籤/搜索