前端的發展能夠說是一個快速崛起的歷程了,不斷的進化,不斷的出現新的Api,新的功能,前端這個領域真的是一個發展飛快的領域,你前一天剛學會XXX的的運用,後一天某某某就革新了一項新的技術,你在感嘆學不動的同時,不得不繼續學習。扯遠了,回到咱們今天的主題。。。javascript
三年前入職的時候仍是一個只會使用Ajax和Jquery 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
提供了對Request
和Response
(以及其餘與網絡請求有關的)對象的通用定義。使之從此能夠被使用到更多地應用場景中:不管是service workers
、Cache 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 工做原理
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();
複製代碼
經過XMLHttpRequest
生成的請求能夠有兩種方式來獲取數據,異步模式
或同步模式
。請求的類型是由這個XMLHttpRequest
對象的open()
方法的第三個參數async
的值決定的。若是該參數的值爲false
,則該XMLHttpRequest
請求以同步模式進行,不然該過程將以異步模式完成。
注意
:因爲對用戶體驗的糟糕效果,從Gecko 30.0(Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27)
版本開始,在主線程上的同步請求已經被棄用
。
W3C
規範定義了XMLHttpRequest
對象的幾種類型的響應屬性。這些屬性告訴客戶端關於XMLHttpRequest
返回狀態的重要信息。一些處理非文本返回類型的用例可能包含一些下面章節描述的操做和分析。
1-2-一、分析並操做 responseXML屬性
若是你使用 XMLHttpRequest
來得到一個遠程的 XML 文檔的內容,responseXML
屬性將會是一個由 XML
文檔解析而來的 DOM
對象,這很難被操做和分析。這裏有五種主要的分析 XML 文檔的方式
:
1-2-二、解析和操做包含 HTML 文檔的 responseText 屬性
若是使用 XMLHttpRequest
從遠端獲取一個 HTML
頁面,則全部 HTML 標記會以字符串的形式存放在responseText
屬性裏,這樣就使得操做和解析這些標記變得困難。解析這些HTML標記主要有三種方式
:
- 1.使用
XMLHttpRequest.responseXML
屬性。- 2.將內容經過
fragment.body.innerHTML
注入到一個 文檔片斷 中,並遍歷 DOM 中的片斷。- 3.若是你預先知道 HTML 文檔的內容,你可使用
RegExp
。若是你用 RegExp 掃描時受到換行符的影響,你也許想要刪除全部的換行符。 然而,這種方法是"最後手段",由於若是 HTML 代碼發生輕微變化,該方法將可能失敗。
儘管 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();
複製代碼
XMLHttpRequest
提供了各類在請求被處理期間發生的事件以供監聽。這包括按期進度通知、 錯誤通知,等等。
支持 DOM 的 progress
事件監測之於 XMLHttpRequest
傳輸,遵循 Web API
進度事件規範 : 這些事件實現了 ProgressEvent 接口。
XMLHttpRequest
的實例有兩種方式提交表單:
- 使用 AJAX
- 使用 FormData API
第二種方式( 使用 FormData API )是最簡單最快捷的,可是缺點是被收集的數據沒法使用JSON.stringify()轉換爲一個 JSON字符串。 第一種方式反而是最複雜的但也是最靈活和最強大。
請求方式這裏不作太多贅述,一個傳送門,有興趣的小夥伴能夠本身去查閱一下。
$.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() |
編碼表單元素集爲 names 和 values 的數組 |
對於Jquery Ajax來講我是特別的喜歡,只是人在進步,新的知識中終歸會替代那些舊的。
總結: 這裏引用
海賊王
白鬍子說的一句話,如圖,加載不出來就別看了~~
先來看看官網的案例:
執行 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規範,從它的官網上能夠看到它有如下幾條特性:
XSRF
(Cross Site Request Forgery, 跨站域請求僞造)也稱 XSRF, 是一種網絡的攻擊方式,它在 2007 年曾被列爲互聯網 20 大安全隱患之一。其餘安全隱患,好比 SQL 腳本注入,跨站域腳本攻擊等在近年來已經逐漸爲衆人熟知,不少網站也都針對他們進行了防護。然而,對於大多數人來講,CSRF 卻依然是一個陌生的概念。即使是大名鼎鼎的 Gmail, 在 2007 年末也存在着 CSRF 漏洞,從而被黑客攻擊而使 Gmail 的用戶形成巨大的損失。客戶端支持防護 XSRF
,是怎麼作到的呢,就是讓你的每一個請求都帶一個從cookie
中拿到的key
, 根據瀏覽器同源策略,假冒的網站是拿不到你cookie
中得key
的,這樣,後臺就能夠輕鬆辨別出這個請求是不是用戶在假冒網站上的誤導輸入,從而採起正確的策略。
axios建立請求時能夠用的配置選項。只有 url 是必需的。若是沒有指定 method,請求將默認使用 get 方法。請求配置傳送門
Axios
既提供了併發的封裝,體積也較小,也沒有下文會提到的fetch
的各類問題,當之無愧是如今最應該選用的請求的方式。
Fetch
提供了對Request
和Response
(以及其餘與網絡請求有關的)對象的通用定義。Fetch
是一個現代的概念, 等同於XMLHttpRequest
。它提供了許多與XMLHttpRequest相同的功能,但被設計成更具可擴展性和高效性。
Fetch API
提供了一個 JavaScript
接口,用於訪問和操縱HTTP管道
的部分,例如請求和響應。它還提供了一個全局 fetch()
方法,該方法提供了一種簡單,合理的方式來跨網絡異步獲取資源。
請注意,fetch規範與jQuery.ajax()主要有兩種方式的不一樣,牢記:
Promise
不會被標記爲 reject
, 即便該 HTTP 響應的狀態碼是 404
或 500
。相反,它會將 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的優勢:
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
參考來源於MDN