1. 程式人生 > >Jquery ajax, Axios, Fetch區別

Jquery ajax, Axios, Fetch區別

1 JQuery ajax

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

這個我就不用多言了把,是對原生XHR的封裝,除此以外還增添了對JSONP的支援。有一說一的說一句,JQuery ajax經過多年的更新維護,真的已經是非常的方便了,優點無需多言;如果是硬要舉出幾個缺點,那可能只有

  • 本身是針對MVC的程式設計,不符合現在前端MVVM的浪潮
  • 基於原生的XHR開發,XHR本身的架構不清晰,已經有了fetch的替代方案
  • JQuery整個專案太大,單純使用ajax卻要引入整個JQuery非常的不合理(採取個性化打包的方案又不能享受CDN服務)

儘管JQuery對我們前端的開發工作曾有著(現在也仍然有著)深遠的影響,但是我們可以看到隨著VUE,REACT新一代框架的興起,以及ES規範的完善,更多API的更新,JQuery這種大而全的JS庫,未來的路會越走越窄。

總結:廉頗老矣,尚能飯,但是總有飯不動的一天。

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
  • 提供了一些併發請求的介面(重要,方便了很多的操作)

這個支援防止CSRF其實挺好玩的,是怎麼做到的呢,就是讓你的每個請求都帶一個從cookie中拿到的key, 根據瀏覽器同源策略,假冒的網站是拿不到你cookie中得key的,這樣,後臺就可以輕鬆辨別出這個請求是否是使用者在假冒網站上的誤導輸入,從而採取正確的策略。

Axios既提供了併發的封裝,也沒有下文會提到的fetch的各種問題,而且體積也較小,當之無愧現在最應該選用的請求的方式。

總結:誰敢橫刀立馬,唯我Axios將軍!

3 Fetch

fetch號稱是AJAX的替代品,它的好處在《傳統 Ajax 已死,Fetch 永生》中提到有以下幾點:

  • 符合關注分離,沒有將輸入、輸出和用事件來跟蹤的狀態混雜在一個物件裡
  • 更好更方便的寫法,諸如:
try {
  let response = await fetch(url);
  let data = response.json();
  console.log(data);
} catch(e) {
  console.log("Oops, error", e);
}

坦白說,上面的理由對我來說完全沒有什麼說服力,因為不管是Jquery還是Axios都已經幫我們把xhr封裝的足夠好,使用起來也足夠方便,為什麼我們還要花費大力氣去學習fetch?

我認為fetch的優勢主要優勢就是:

  • 更加底層,提供的API豐富(request, response)
  • 脫離了XHR,是ES規範裡新的實現方式

大家都喜歡新的東西,坦白說,作為一個前端工程師,我在使用原生XHR的時候,儘管偶爾覺得寫的醜陋,但是在使用了JQuery和axios之後,已經對這一塊完全無所謂了。當然,如果新的fetch能做的同樣好,我為了不掉隊也會選擇使用fetch。這個道理其實很好理解:你有一架殲8,魔改了N次,效能達到了殲10的水準,但是要是有個人給你拿來一架新的殲10,你也會毫不猶豫的選擇新的殲10——不僅僅是新,也代表了還有新的魔改潛力。

但是我最近在使用fetch的時候,也遇到了不少的問題:

  • fetch是一個低層次的API,你可以把它考慮成原生的XHR,所以使用起來並不是那麼舒服,需要進行封裝

例如:

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

看到這裡,你心裡一定有個疑問,這鬼東西就是個半拉子工程嘛,我還是回去用Jquery或者Axios算了——其實我就是這麼打算的。但是,必須要提出的是,我發現fetch在前端的應用上有一項xhr怎麼也比不上的能力:跨域的處理。

我們都知道因為同源策略的問題,瀏覽器的請求是可能隨便跨域的——一定要有跨域頭或者藉助JSONP,但是,fetch中可以設定mode為"no-cors"(不跨域),如下所示:

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

這樣之後我們會得到一個type為“opaque”的返回。需要指出的是,這個請求是真正抵達過後臺的,所以我們可以使用這種方法來進行資訊上報,在我們之前的image.src方法中多出了一種選擇,另外,我們在network中可以看到這個請求後臺設定跨域頭之後的實際返回,有助於我們提前除錯介面(當然,通過chrome外掛我們也可以做的到)。總之,fetch現在還不是很好用,我嘗試過幾個fetch封裝的包,都還不盡如人意。

總結:酋長的孩子,還需成長

總結

如果你是直接拉到文章底部的,只需要知道現在無腦使用axios即可,Jquery老邁笨拙,fetch年輕稚嫩,只有Axios正當其年!