Jquery ajax, Axios, Fetch區別之我見(轉載)

來源:https://segmentfault.com/a/1190000012836882

引言

前端技術真是一個發展飛快的領域,我三年前入職的時候只有原生XHR和Jquery ajax,咱們還曾被JQuery 1.9版本版本如下不支持大文件請求這個問題卡了半天(最後本身寫了原生的XHR請求)。一晃眼,JQuery ajax早已不能專美於前,axios和fetch都已經開始分別搶佔「請求」這個前端高地。本文將會嘗試着闡述他們之間的區別,並給出本身的一些理解。html

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庫,將來的路會越走越窄。node

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

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規範,從它的官網上能夠看到它有如下幾條特性:ios

  • 從 node.js 建立 http 請求
  • 支持 Promise API
  • 客戶端支持防止CSRF
  • 提供了一些併發請求的接口(重要,方便了不少的操做)

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

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

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

3 Fetch

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

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

坦白說,上面的理由對我來講徹底沒有什麼說服力,由於不論是Jquery仍是Axios都已經幫咱們把xhr封裝的足夠好,使用起來也足夠方便,爲何咱們還要花費大力氣去學習fetch?chrome

我認爲fetch的優點主要優點就是:編程

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

你們都喜歡新的東西,坦白說,做爲一個前端工程師,我在使用原生XHR的時候,儘管偶爾以爲寫的醜陋,可是在使用了JQuery和axios以後,已經對這一塊徹底無所謂了。固然,若是新的fetch能作的一樣好,我爲了避免掉隊也會選擇使用fetch。這個道理其實很好理解:你有一架殲8,魔改了N次,性能達到了殲10的水準,可是要是有我的給你拿來一架新的殲10,你也會堅決果斷的選擇新的殲10——不只僅是新,也表明了還有新的魔改潛力。json

可是我最近在使用fetch的時候,也遇到了很多的問題:

  • fetch是一個低層次的API,你能夠把它考慮成原生的XHR,因此使用起來並非那麼舒服,須要進行封裝

例如:

1)fetch只對網絡請求報錯,對400,500都當作成功的請求,須要封裝去處理
2)fetch默認不會帶cookie,須要添加配置項
3)fetch不支持abort,不支持超時控制,使用setTimeout及Promise.reject的實現的超時控制並不能阻止請求過程繼續在後臺運行,形成了流量的浪費
4)fetch沒有辦法原生監測請求的進度,而XHR能夠

PS: fetch的具體問題你們能夠參考:《fetch沒有你想象的那麼美》《fetch使用的常見問題及解決方法

看到這裏,你內心必定有個疑問,這鬼東西就是個半拉子工程嘛,我仍是回去用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正當其年!

相關文章
相關標籤/搜索