Ajax,jQuery ajax,axios和fetch介紹、區別以及優缺點

引言

前端的發展能夠說是一個快速崛起的歷程了,不斷的進化,不斷的出現新的Api,新的功能,前端這個領域真的是一個發展飛快的領域,你前一天剛學會XXX的的運用,後一天某某某就革新了一項新的技術,你在感嘆學不動的同時,不得不繼續學習。扯遠了,回到咱們今天的主題。。。javascript

三年前入職的時候仍是一個只會使用AjaxJquery Ajax的菜鳥,因爲早期Jquery不支持大文件請求的問題,能夠原生的XHR解決。html

如下篇幅較長,建議收藏了慢慢收看。在這裏學到的確定會對你有所幫助前端

區別介紹

「Ajax」:vue

全稱Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)最先出現的發送後端請求技術,隸屬於原始js中,核心使用XMLHttpRequest對象,多個請求之間若是有前後關係的話,就會出現回調地獄。java

「Jquery Ajax」:node

是 jQuery 底層 AJAX 實現。簡單易用的高層實現見 $.get, $.post 等。$.ajax() 返回其建立的 XMLHttpRequest 對象。大多數狀況下你無需直接操做該函數,除非你須要操做不經常使用的選項,以得到更多的靈活性。jQuery ajax - ajax() 方法react

「Axios」:jquery

axios不是原生JS的,須要進行安裝,它不但能夠在客戶端使用,也能夠在nodejs端使用。Axios也能夠在請求和響應階段進行攔截。一樣也是基於Promise對象的。特性:從瀏覽器中建立 XMLHttpRequests、從 node.js 建立 http 請求、支持 Promise API、攔截請求和響應等。Axios 中文文檔傳送門ios

「Fetch」:git

Fetch 提供了對 RequestResponse (以及其餘與網絡請求有關的)對象的通用定義。使之從此能夠被使用到更多地應用場景中:不管是service workersCache API、又或者是其餘處理請求和響應的方式,甚至是任何一種須要你本身在程序中生成響應的方式。Fetch號稱是AJAX的替代品,是在ES6出現的,使用了ES6中的Promise對象。Fetch是基於promise設計的。Fetch的代碼結構比起ajax簡單多了,參數有點像jQuery ajax。可是,必定記住fetch不是ajax的進一步封裝,而是原生js。Fetch函數就是原生js,沒有使用XMLHttpRequest對象。

細談

詳細的描述一下Ajax,jQuery ajax,axios和fetch區別,讓咱們繼續往下研究。

AJAX = 異步 JavaScript 和 XML。

AJAX 是一種用於建立快速動態網頁的技術。

經過在後臺與服務器進行少許數據交換,AJAX 可使網頁實現異步更新。這意味着能夠在不從新加載整個網頁的狀況下,對網頁的某部分進行更新。

AJAX 工做原理

1、Ajax

XMLHttpRequest 讓發送一個HTTP請求變得很是容易。你只須要簡單的建立一個請求對象實例,打開一個URL,而後發送這個請求。當傳輸完畢後,結果的HTTP狀態以及返回的響應內容也能夠從請求對象中獲取。簡單的來敘述一下這個過程,往下看:

function reqListener () {
  console.log(this.responseText);
}

var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.open("get", "newFile.txt", true);
oReq.send();
複製代碼
1-1 請求類型

經過XMLHttpRequest生成的請求能夠有兩種方式來獲取數據,異步模式同步模式。請求的類型是由這個XMLHttpRequest對象的open()方法的第三個參數async的值決定的。若是該參數的值爲false,則該XMLHttpRequest請求以同步模式進行,不然該過程將以異步模式完成。

注意:因爲對用戶體驗的糟糕效果,從Gecko 30.0(Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27)版本開始,在主線程上的同步請求已經被棄用

1-2 處理響應

W3C規範定義了XMLHttpRequest對象的幾種類型的響應屬性。這些屬性告訴客戶端關於XMLHttpRequest返回狀態的重要信息。一些處理非文本返回類型的用例可能包含一些下面章節描述的操做和分析。

1-2-一、分析並操做 responseXML屬性

若是你使用 XMLHttpRequest 來得到一個遠程的 XML 文檔的內容,responseXML 屬性將會是一個由 XML 文檔解析而來的 DOM 對象,這很難被操做和分析。這裏有五種主要的分析 XML 文檔的方式

  • 1.使用 XPath 定位到文檔的指定部分。
  • 2.手工的 解析和序列化 XML 爲字符串或對象。
  • 3.使用 XMLSerializer 把 DOM 樹序列化成字符串或文件。
  • 4.若是你預先知道 XML 文檔的內容,你可使用 RegExp。若是你用 RegExp 掃描時受到換行符的影響,你也許想要刪除全部的換行符。然而,這種方法是"最後手段",由於若是 XML 代碼發生輕微變化,該方法將可能失敗。

1-2-二、解析和操做包含 HTML 文檔的 responseText 屬性

若是使用 XMLHttpRequest 從遠端獲取一個 HTML 頁面,則全部 HTML 標記會以字符串的形式存放在responseText 屬性裏,這樣就使得操做和解析這些標記變得困難。解析這些HTML標記主要有三種方式

  • 1.使用 XMLHttpRequest.responseXML 屬性。
  • 2.將內容經過 fragment.body.innerHTML 注入到一個 文檔片斷 中,並遍歷 DOM 中的片斷。
  • 3.若是你預先知道 HTML 文檔的內容,你可使用 RegExp 。若是你用 RegExp 掃描時受到換行符的影響,你也許想要刪除全部的換行符。 然而,這種方法是"最後手段",由於若是 HTML 代碼發生輕微變化,該方法將可能失敗。
1-3 處理二進制數據

儘管 XMLHttpRequest 通常用來發送和接收文本數據,但其實也能夠發送和接受二進制內容。有許多通過良好測試的方法來強制使用 XMLHttpRequest 發送二進制數據。利用 XMLHttpRequest.overrideMimeType() 方法是一個解決方案,雖然它並非一個標準方法。

var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
// retrieve data unprocessed as a binary string
oReq.overrideMimeType("text/plain; charset=x-user-defined");
複製代碼

在 XMLHttpRequest Level 2 規範中新加入了 responseType 屬性 ,使得發送和接收二進制數據變得更加容易。

var oReq = new XMLHttpRequest();

oReq.onload = function(e) {
  var arraybuffer = xhr.response; // not responseText
  /* ... */
}
oReq.open("GET", url, true);
oReq.responseType = "arraybuffer";
oReq.send();
複製代碼
1-4 監測進度

XMLHttpRequest 提供了各類在請求被處理期間發生的事件以供監聽。這包括按期進度通知、 錯誤通知,等等。

支持 DOM 的 progress 事件監測之於 XMLHttpRequest 傳輸,遵循 Web API 進度事件規範 : 這些事件實現了 ProgressEvent 接口。

1-5 提交表單和上傳文件

XMLHttpRequest 的實例有兩種方式提交表單:

  • 使用 AJAX
  • 使用 FormData API

第二種方式( 使用 FormData API )是最簡單最快捷的,可是缺點是被收集的數據沒法使用JSON.stringify()轉換爲一個 JSON字符串。 第一種方式反而是最複雜的但也是最靈活和最強大。

請求方式這裏不作太多贅述,一個傳送門,有興趣的小夥伴能夠本身去查閱一下。

2、Jquery Ajax

$.ajax({
  url: "/api/getWeather",
  data: {
    zipcode: 97201
  },
  success: function( result ) {
    $( "#weather-temp" ).html( "<strong>" + result + "</strong> degrees" );
  }
});
複製代碼

傳統 Ajax 指的是 XMLHttpRequest(XHR), 最先出現的發送後端請求技術,隸屬於原始js中,核心使用XMLHttpRequest對象,多個請求之間若是有前後關係的話,就會出現回調地獄。Jquery Ajax的出現是對原生XHR的封裝,除此之外還增添了對JSONP的支持,Jquery Ajax通過多年的更新維護,真的已是很是的方便了,可是隨着react,vue,angular新一代框架的興起,以及ES規範的完善,更多API的更新,它逐漸暴露了本身的不足:

  • 1.自己是針對MVC的編程,不符合如今前端MVVM的浪潮
  • 2.基於原生的XHR開發,XHR自己的架構不清晰,已經有了fetch的替代方案
  • 3.JQuery整個項目太大,單純使用ajax卻要引入整個JQuery很是的不合理(採起個性化打包的方案又不能享受CDN服務)
  • 4.不符合關注分離(Separation of Concerns)的原則
  • 5.配置和調用方式很是混亂,並且基於事件的異步模型不友好

默認狀況下,Ajax 請求使用 GET 方法。若是要使用 POST 方法,能夠設定 type 參數值。這個選項也會影響 data 選項中的內容如何發送到服務器。

data 選項既能夠包含一個查詢字符串,好比 key1=value1&key2=value2 ,也能夠是一個映射,好比 {key1: 'value1', key2: 'value2'} 。若是使用了後者的形式,則數據再發送器會被轉換成查詢字符串。這個處理過程也能夠經過設置 processData 選項爲 false 來回避。若是咱們但願發送一個 XML 對象給服務器時,這種處理可能並不合適。而且在這種狀況下,咱們也應當改變 contentType 選項的值,用其餘合適的 MIME 類型來取代默認的 application/x-www-form-urlencoded

var list = {}; 
$.ajax({
    //請求方式 POST || GET
    type : "POST", 
    //請求的媒體類型
    contentType: "application/json;charset=UTF-8",
    //請求地址
    url : "http://127.0.0.1/xxxx/",
    //數據,json字符串
    data : JSON.stringify(list),
    //請求成功
    success : function(result) {
        console.log(result);
    },
    //請求失敗,包含具體的錯誤信息
    error : function(e){
        console.log(e.status);
        console.log(e.responseText);
    }
});
複製代碼

下面的表格列出了 jQuery AJAX 方法:

方法 描述
$.ajax() 執行異步 AJAX 請求
$.ajaxPrefilter() 在每一個請求發送以前且被 $.ajax() 處理以前,處理自定義 Ajax 選項或修改已存在選項
$.ajaxSetup() 爲未來的 AJAX 請求設置默認值
$.ajaxTransport() 建立處理 Ajax 數據實際傳送的對象
$.get() 使用 AJAX 的 HTTP GET 請求從服務器加載數據
$.getJSON() 使用 HTTP GET 請求從服務器加載 JSON 編碼的數據
$.getScript() 使用 AJAX 的 HTTP GET 請求從服務器加載並執行 JavaScript
$.param() 建立數組或對象的序列化表示形式(可用於 AJAX 請求的 URL 查詢字符串)
$.post() 使用 AJAX 的 HTTP POST 請求從服務器加載數據
ajaxComplete() 規定 AJAX 請求完成時運行的函數
ajaxError() 規定 AJAX 請求失敗時運行的函數
ajaxSend() 規定 AJAX 請求發送以前運行的函數
ajaxStart() 規定第一個 AJAX 請求開始時運行的函數
ajaxStop() 規定全部的 AJAX 請求完成時運行的函數
ajaxSuccess() 規定 AJAX 請求成功完成時運行的函數
load() 從服務器加載數據,並把返回的數據放置到指定的元素中
serialize() 編碼表單元素集爲字符串以便提交
serializeArray() 編碼表單元素集爲 namesvalues 的數組

對於Jquery Ajax來講我是特別的喜歡,只是人在進步,新的知識中終歸會替代那些舊的。

總結: 這裏引用海賊王白鬍子說的一句話,如圖,加載不出來就別看了~~

3、Axios

先來看看官網的案例:

執行 GET 請求

// 爲給定 ID 的 user 建立請求
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// 上面的請求也能夠這樣作
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
複製代碼

執行 POST 請求

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
複製代碼

執行多個併發請求

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) {
    // 兩個請求如今都執行完成
  }));
複製代碼

Vue2.0以後,尤雨溪推薦你們用axios替換JQuery ajax`,將來App的趨勢是輕量化和細化,能解決問題的應用就是好應用,想必讓Axios進入了不少人的目光中。Axios本質上也是對原生XHR的封裝,只不過它是Promise的實現版本,能夠用在瀏覽器和 node.js 中,符合最新的ES規範,從它的官網上能夠看到它有如下幾條特性:

  • 從瀏覽器中建立 XMLHttpRequests
  • 從 node.js 建立 http 請求
  • 支持 Promise API
  • 攔截請求和響應
  • 轉換請求數據和響應數據
  • 取消請求
  • 自動轉換 JSON 數據
  • 客戶端支持防護 XSRF

XSRFCross Site Request Forgery, 跨站域請求僞造)也稱 XSRF, 是一種網絡的攻擊方式,它在 2007 年曾被列爲互聯網 20 大安全隱患之一。其餘安全隱患,好比 SQL 腳本注入,跨站域腳本攻擊等在近年來已經逐漸爲衆人熟知,不少網站也都針對他們進行了防護。然而,對於大多數人來講,CSRF 卻依然是一個陌生的概念。即使是大名鼎鼎的 Gmail, 在 2007 年末也存在着 CSRF 漏洞,從而被黑客攻擊而使 Gmail 的用戶形成巨大的損失。客戶端支持防護 XSRF,是怎麼作到的呢,就是讓你的每一個請求都帶一個從cookie中拿到的key, 根據瀏覽器同源策略,假冒的網站是拿不到你cookie中得key的,這樣,後臺就能夠輕鬆辨別出這個請求是不是用戶在假冒網站上的誤導輸入,從而採起正確的策略。

axios建立請求時能夠用的配置選項。只有 url 是必需的。若是沒有指定 method,請求將默認使用 get 方法。請求配置傳送門

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

4、Fetch

Fetch 提供了對 RequestResponse (以及其餘與網絡請求有關的)對象的通用定義。 Fetch 是一個現代的概念, 等同於 XMLHttpRequest。它提供了許多與XMLHttpRequest相同的功能,但被設計成更具可擴展性和高效性。

Fetch API 提供了一個 JavaScript接口,用於訪問和操縱HTTP管道的部分,例如請求和響應。它還提供了一個全局 fetch()方法,該方法提供了一種簡單,合理的方式來跨網絡異步獲取資源。

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

  • 當接收到一個表明錯誤的 HTTP 狀態碼時,從 fetch()返回的 Promise 不會被標記爲 reject, 即便該 HTTP 響應的狀態碼是 404500。相反,它會將 Promise 狀態標記爲 resolve可是會將 resolve 的返回值的 ok 屬性設置爲 false ),僅當網絡故障時或請求被阻止時,纔會標記爲 reject
  • 默認狀況下,fetch 不會從服務端發送或接收任何 cookies, 若是站點依賴於用戶 session,則會致使未經認證的請求(要發送 cookies,必須設置 credentials 選項)。自從2017年8月25往後,默認的credentials政策變動爲same-originFirefox也在61.0b13中改變默認值

一個基本的 fetch請求設置起來很簡單。看看下面的代碼:

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

這裏咱們經過網絡獲取一個JSON文件並將其打印到控制檯。最簡單的用法是隻提供一個參數用來指明想fetch()到的資源路徑,而後返回一個包含響應結果的promise(一個 Response 對象)

固然它只是一個 HTTP 響應,而不是真的JSON。爲了獲取JSON的內容,咱們須要使用 json()方法(在Bodymixin 中定義,被 Request 和 Response 對象實現)。

fetch() 接受第二個可選參數,一個能夠控制不一樣配置的 init 對象:

// Example POST method implementation:

postData('http://example.com/answer', {answer: 42})
  .then(data => console.log(data)) // JSON from `response.json()` call
  .catch(error => console.error(error))

function postData(url, data) {
  // Default options are marked with *
  return fetch(url, {
    body: JSON.stringify(data), // must match 'Content-Type' header
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, same-origin, *omit
    headers: {
      'user-agent': 'Mozilla/4.0 MDN Example',
      'content-type': 'application/json'
    },
    method: 'POST', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, cors, *same-origin
    redirect: 'follow', // manual, *follow, error
    referrer: 'no-referrer', // *client, no-referrer
  })
  .then(response => response.json()) // parses response to JSON
}
複製代碼

fetch的優勢:

  • 1.語法簡潔,更加語義化
  • 2.基於標準 Promise 實現,支持 async/await
  • 3.同構方便,使用 isomorphic-fetch
  • 4.更加底層,提供的API豐富(request, response)
  • 5.脫離了XHR,是ES規範裏新的實現方式

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_API

參考資料MDC AJAX introduction

參考來源於MDN

相關文章
相關標籤/搜索