fetch
,它和XMLHttpRequest
有許多類似的功能,可是相比XMLHttpRequest
,fetch
被設計成更具可擴展性和高效性。江湖上一直流傳着 「傳統ajax已死,fetch永生」的說法,下面詳細說下兩者XMLHttpRequest
請求數據var xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.responseType = 'json'; xhr.onload = function() { console.log(xhr.response); }; xhr.onerror = function() { console.log("Oops, error"); }; xhr.send();
fetch
請求數據fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log("Oops, error", e))
兩段代碼相比之下,fetch
更爲簡潔,並且fetch
請求屬於promise
結構,直接.then()
方法處理回調數據,當出錯時,會執行catch
方法,並且promise
避免了回調金字塔的問題。javascript
fetch
瀏覽器支持狀況目前谷歌瀏覽器對fetch的支持良好,具體支持狀況以下圖html
固然,你也能夠去這裏查看can i usejava
fetch
請求的四種方式fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log("Oops, error", e))
若是須要傳遞參數,須要拼接在url
。
後面這裏的調用的第一個then
函數裏面,返回結果是一個可讀流形式git
若是請求的是json數據,須要調用response.json()
(這裏的response
是傳遞的參數)將可讀流解析爲json數據,在下一個then
方法中,就能夠獲得想要的json數據了es6
同理,若是請求的txt文本數據,則須要調用response.text()
來解析...更多調用的解析方法以下github
response.arrayBuffer() 讀取 Response對象而且將它設置爲已讀(由於Responses對象被設置爲了 stream 的方式,因此它們只能被讀取一次) ,並返回一個被解析爲ArrayBuffer格式的promise對象 response.blob() 讀取 Response對象而且將它設置爲已讀(由於Responses對象被設置爲了 stream 的方式,因此它們只能被讀取一次) ,並返回一個被解析爲Blob格式的promise對象 response.formData() 讀取Response對象而且將它設置爲已讀(由於Responses對象被設置爲了 stream 的方式,因此它們只能被讀取一次) ,並返回一個被解析爲FormData格式的promise對象 response.json() 讀取 Response對象而且將它設置爲已讀(由於Responses對象被設置爲了 stream 的方式,因此它們只能被讀取一次) ,並返回一個被解析爲JSON格式的promise對象 response.text() 讀取 Response對象而且將它設置爲已讀(由於Responses對象被設置爲了 stream 的方式,因此它們只能被讀取一次) ,並返回一個被解析爲USVString格式的promise對象
對於catch
方法,只有報程序出錯的時候纔會執行。ajax
fetch(url,{ method:'POST', headers:{ 'Content-type':'application/json'// 設置請求頭數據類型 }, body:data }) .then(res=>res.json()) .then(data=>console.log(data))
method
:設置設置請求的方式,默認是get
,另外還有PUT
、DELETE
headers
:設置請求頭信息,固然,這裏面還能夠設置別的信息,好比:json
var u = new URLSearchParams(); u.append('method', 'flickr.interestingness.getList'); u.append('api_key', '<insert api key here>'); u.append('format', 'json'); u.append('nojsoncallback', '1'); fetch(url,{ method:'POST', headers:u, body:data }) .then(res=>res.json()) .then(data=>console.log(data))
另外,fetch
能夠在header
中設置CORS
跨域後端
u.append("Access-Control-Allow-Origin", "*"); u.append("Access-Control-Allow-Headers", "X-Requested-With"); u.append("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); u.append("X-Powered-By",' 3.2.1')
CORS
,fetch
提供了三種模式,其中no-cors
能夠繼續訪問服務器fetch
的mode
配置項有3個值,以下:api
same-origin
:該模式是不容許跨域的,它須要遵照同源策略,不然瀏覽器會返回一個error告知不能跨域;其對應的response type爲basic。cors
: 該模式支持跨域請求,顧名思義它是以CORS
的形式跨域;固然該模式也能夠同域請求不須要後端額外的CORS
支持;其對應的response type
爲cors
。no-cors
: 該模式用於跨域請求可是服務器不帶CORS
響應頭,也就是服務端不支持CORS
;這也是fetch
的特殊跨域請求方式;其對應的response type
爲opaque
。針對跨域請求,cors模式是常見跨域請求實現,可是fetch自帶的no-cors跨域請求模式則較爲陌生,該模式有一個比較明顯的特色:
該模式容許瀏覽器發送本次跨域請求,可是不能訪問響應返回的內容,這也是其response type爲opaque透明的緣由,以下圖:
呃,感受這樣雖然解決能跨域問題,可是請求不到任何數據,仍是沒有卵用...
注意: cors 支持 三種content-type
不支持 application/json
body
:須要傳遞的參數
fetch
請求默認是不會攜帶cookie
信息,若是想要攜帶,須要在手動設置
fetch(url, { method: 'POST', headers:{ 'Content-type':'application/json'// 設置請求頭數據類型 }, credentials: "include" })
credentials: "include"
設置請求頭攜帶cookie
信息
fetch(url,{ method:'PUT', headers:{ 'Content-type':'application/json'// 設置請求頭數據類型 }, body:data }) .then(res=>res.json()) .then(data=>console.log(data))
fetch(url,{ method:'DELETE', headers:{ 'Content-type':'application/json'// 設置請求頭數據類型 }, body:data }) .then(res=>res.json()) .then(data=>console.log(data))
其實,post
,put
,delete
,這三個請求代碼上差很少,只是method中對應不一樣的請求方法不一樣而已。
fetch
的API代碼<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script src="easyhttp.js"></script> <script src="app.js"></script> </body> </html>
const url = 'http://jsonplaceholder.typicode.com/users'; let easyHttp = new EasyHttp; // 請求數據 easyHttp.get(url) .then(res=>console.log(res)) .catch(err=>console.log(err)) // 發送數據 const data = { name:"Henry", username:"露絲", email:"lusi@qq.com" }; // easyHttp.post(url,data) // .then(res=>console.log(res)) // .catch(err=>console.log(err)) // 修改數據 // easyHttp.put(url+'/10',data) // .then(res=>console.log(res)) // .catch(err=>console.log(err)) easyHttp.delete(url+'/2',data) .then(res=>console.log(res)) .catch(err=>console.log(err))
/** * fetch 增刪改查 的API封裝 */ class EasyHttp{ // get 請求 get(url){ return new Promise((resolve,reject)=>{ fetch(url) .then(res=>res.json()) .then(data=>resolve(data)) .catch(err=>reject(err)) }) } // post 請求 post(url,data){ return new Promise((resolve,reject)=>{ fetch(url,{ method:'POST', headers:{ 'Content-type':'application/json'// 設置請求頭數據類型 }, body:data }) .then(res=>res.json()) .then(data=>resolve(data)) .then(err=>reject(err)) }) } // put 請求修改數據 put(url,data){ return new Promise((resolve,reject)=>{ fetch(url,{ method:'PUT', headers:{ 'Content-type':'application/json'// 設置請求頭數據類型 }, body:data }) .then(res=>res.json()) .then(data=>resolve(data)) .then(err=>reject(err)) }) } // delete 刪除數據 delete(url,data){ return new Promise((resolve,reject)=>{ fetch(url,{ method:'DELETE', headers:{ 'Content-type':'application/json'// 設置請求頭數據類型 }, body:data }) .then(res=>res.json()) .then(data=>'刪除數據成功。。。') .then(err=>reject(err)) }) } }
源碼地址:戳一下
fetch
和XMLHttpRequest
相比,主要有如下優勢: