1. 程式人生 > >非同步請求xhr、ajax、axios與fetch的區別比較

非同步請求xhr、ajax、axios與fetch的區別比較

目錄

  • 1. XMLHttpRequest物件
  • 2. jQuery ajax
  • 3. axios
  • 4. fetch
  • 參考

why: 為什麼會出現不同的方法呢?
what: 這些都是非同步請求資料的方法。在不重新重新整理頁面的情況下與伺服器通訊,交換資料,或更新頁面。
how:他們都有各自的特點。

1. XMLHttpRequest物件

現代瀏覽器,最開始與伺服器交換資料,都是通過XMLHttpRequest物件。它可以使用JSON、XML、HTML和text文字等格式傳送和接收資料。

它給我們帶來了很多好處。

  1. 不重新載入頁面的情況下更新網頁
  2. 在頁面已載入後從伺服器請求/接收資料
  3. 在後臺向伺服器傳送資料。

但是,它也有一些缺點:

  1. 使用起來也比較繁瑣,需要設定很多值。
  2. 早期的IE瀏覽器有自己的實現,這樣需要寫相容程式碼。
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 {
    // TODO 處理響應
    if (xhr.readyState === XMLHttpRequest.DONE) {
      // XMLHttpRequest.DONE 對應值是 4
      // Everything is good, the response was received.
      if (xhr.status === 200) {
        // Perfect!
      } else {
        // There was a problem with the request.
        // For example, the response may hava a 404 (Not Found)
        // or 500 (Internal Server Error) response code.
      }
    } else {
      // Not ready yet
    }
  } catch (e) {
    // 通訊錯誤的事件中(例如伺服器宕機)
    alert('Caught Exception: ' + e.description)
  }
}

2. jQuery ajax

為了更快捷的操作DOM,並且規避一些瀏覽器相容問題,產生了jQuery。它裡面的AJAX請求也相容了各瀏覽器,可以有簡單易用的方法$.get$.post。簡單點說,就是對XMLHttpRequest物件的封裝。

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

優點:

  1. 對原生XHR的封裝,做了相容處理,簡化了使用。
  2. 增加了對JSONP的支援,可以簡單處理部分跨域。

缺點:

  1. 如果有多個請求,並且有依賴關係的話,容易形成回撥地獄。
  2. 本身是針對MVC的程式設計,不符合現在前端MVVM的浪潮。
  3. ajax是jQuery中的一個方法。如果只是要使用ajax卻要引入整個jQuery非常的不合理。

3. axios

Axios是一個基於promiseHTTP庫,可以用在瀏覽器和 node.js 中。它本質也是對原生XMLHttpRequest的封裝,只不過它是Promise的實現版本,符合最新的ES規範。

axios({
    method: 'post',
    url: '/user/12345',
    data: {
      firstName: 'liu',
      lastName: 'weiqin'
    }
  })
  .then(res => console.log(res))
  .catch(err => console.log(err))

Vue2.0之後,尤雨溪大大推薦大家使用axios來請求資料。
優點:

  1. 從瀏覽器中建立XMLHttpRequests
  2. node.js 建立 http 請求
  3. 支援 Promise API
  4. 攔截請求和響應
  5. 轉換請求資料和響應資料
  6. 取消請求
  7. 自動轉換 JSON 資料
  8. 客戶端支援防禦 XSRF

缺點:

  1. 只持現代代瀏覽器.

4. fetch

Fetch API提供了一個 JavaScript 介面,用於訪問和操作HTTP管道的部分,例如請求和響應。它還提供了一個全域性fetch()方法,該方法提供了一種簡單,合理的方式來跨網路非同步獲取資源。
fetch是低層次的API,代替XHR,可以輕鬆處理各種格式,非文字化格式。可以很容易的被其他技術使用,例如Service Workers。但是想要很好的使用fetch,需要做一些封裝處理。

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

優勢:跨域的處理
在配置中,新增mode: 'no-cors'就可以跨域了

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

fetch目前遇到的問題:

  1. fetch只對網路請求報錯,對400500都當做成功的請求,需要封裝去處理
  2. fetch預設不會帶cookie,需要新增配置項。
  3. fetch不支援abort,不支援超時控制,使用setTimeoutPromise.reject的實現超時控制並不能阻止請求過程繼續在後臺執行,造成了流量的浪費。
  4. fetch沒有辦法原生監測請求的進度,而XHR可以。

請注意,fetch規範與jQuery.ajax()主要有兩種方式的不同,牢記:

-. 當接收到一個代表錯誤的 HTTP 狀態碼時,從 fetch()返回的 Promise 不會被標記為 reject, 即使該 HTTP 響應的狀態碼是 404500。相反,它會將 Promise 狀態標記為 resolve (但是會將 resolve的返回值的 ok 屬性設定為 false ),僅當網路故障時或請求被阻止時,才會標記為 reject

-. 預設情況下,fetch 不會從服務端傳送或接收任何 cookies, 如果站點依賴於使用者 session,則會導致未經認證的請求(要傳送 cookies,必須設定 credentials 選項)。

參考

  1. MDN-使用Fetch
  2. 看雲-axios使用說明
  3. jQuery ajax()
  4. XMLHttpRequest