摘要:前言中新增了一種數(shù)據(jù)請(qǐng)求的方式,就是,它和有許多相似的功能,但是相比被設(shè)計(jì)成更具可擴(kuò)展性和高效性。該模式支持跨域請(qǐng)求,顧名思義它是以的形式跨域當(dāng)然該模式也可以同域請(qǐng)求不需要后端額外的支持其對(duì)應(yīng)的為。
前言 ES6中新增了一種HTTP數(shù)據(jù)請(qǐng)求的方式,就是fetch,它和XMLHttpRequest有許多相似的功能,但是相比XMLHttpRequest,fetch被設(shè)計(jì)成更具可擴(kuò)展性和高效性。江湖上一直流傳著 “傳統(tǒng)ajax已死,fetch永生”的說法,下面詳細(xì)說下二者 詳情 1.XMLHttpRequest 請(qǐng)求數(shù)據(jù)
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();2. fetch請(qǐng)求數(shù)據(jù)
fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log("Oops, error", e))
兩段代碼相比之下,fetch更為簡(jiǎn)潔,而且fetch請(qǐng)求屬于promise結(jié)構(gòu),直接.then()方法處理回調(diào)數(shù)據(jù),當(dāng)出錯(cuò)時(shí),會(huì)執(zhí)行catch方法,而且promise避免了回調(diào)金字塔的問題。
3.fetch瀏覽器支持情況目前谷歌瀏覽器對(duì)fetch的支持良好,具體支持情況如下圖
當(dāng)然,你也可以去這里查看can i use
4.fetch請(qǐng)求的四種方式 get請(qǐng)求fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log("Oops, error", e))
如果需要傳遞參數(shù),需要拼接在url。
后面這里的調(diào)用的第一個(gè)then函數(shù)里面,返回結(jié)果是一個(gè)可讀流形式
如果請(qǐng)求的是json數(shù)據(jù),需要調(diào)用response.json()(這里的response是傳遞的參數(shù))將可讀流解析為json數(shù)據(jù),在下一個(gè)then方法中,就可以得到想要的json數(shù)據(jù)了
同理,如果請(qǐng)求的txt文本數(shù)據(jù),則需要調(diào)用response.text()來解析...更多調(diào)用的解析方法如下
response.arrayBuffer() 讀取 Response對(duì)象并且將它設(shè)置為已讀(因?yàn)镽esponses對(duì)象被設(shè)置為了 stream 的方式,所以它們只能被讀取一次) ,并返回一個(gè)被解析為ArrayBuffer格式的promise對(duì)象 response.blob() 讀取 Response對(duì)象并且將它設(shè)置為已讀(因?yàn)镽esponses對(duì)象被設(shè)置為了 stream 的方式,所以它們只能被讀取一次) ,并返回一個(gè)被解析為Blob格式的promise對(duì)象 response.formData() 讀取Response對(duì)象并且將它設(shè)置為已讀(因?yàn)镽esponses對(duì)象被設(shè)置為了 stream 的方式,所以它們只能被讀取一次) ,并返回一個(gè)被解析為FormData格式的promise對(duì)象 response.json() 讀取 Response對(duì)象并且將它設(shè)置為已讀(因?yàn)镽esponses對(duì)象被設(shè)置為了 stream 的方式,所以它們只能被讀取一次) ,并返回一個(gè)被解析為JSON格式的promise對(duì)象 response.text() 讀取 Response對(duì)象并且將它設(shè)置為已讀(因?yàn)镽esponses對(duì)象被設(shè)置為了 stream 的方式,所以它們只能被讀取一次) ,并返回一個(gè)被解析為USVString格式的promise對(duì)象
對(duì)于catch方法,只有報(bào)程序出錯(cuò)的時(shí)候才會(huì)執(zhí)行。
post請(qǐng)求fetch(url,{ method:"POST", headers:{ "Content-type":"application/json"http:// 設(shè)置請(qǐng)求頭數(shù)據(jù)類型 }, body:data }) .then(res=>res.json()) .then(data=>console.log(data))
method:設(shè)置設(shè)置請(qǐng)求的方式,默認(rèn)是get,另外還有PUT、DELETE
headers:設(shè)置請(qǐng)求頭信息,當(dāng)然,這里面還可以設(shè)置別的信息,比如:
var u = new URLSearchParams(); u.append("method", "flickr.interestingness.getList"); u.append("api_key", ""); 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中設(shè)置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")如果服務(wù)器不支持CORS,fetch提供了三種模式,其中no-cors可以繼續(xù)訪問服務(wù)器
fetch的mode配置項(xiàng)有3個(gè)值,如下:
same-origin:該模式是不允許跨域的,它需要遵守同源策略,否則瀏覽器會(huì)返回一個(gè)error告知不能跨域;其對(duì)應(yīng)的response type為basic。
cors: 該模式支持跨域請(qǐng)求,顧名思義它是以CORS的形式跨域;當(dāng)然該模式也可以同域請(qǐng)求不需要后端額外的CORS支持;其對(duì)應(yīng)的response type為cors。
no-cors: 該模式用于跨域請(qǐng)求但是服務(wù)器不帶CORS響應(yīng)頭,也就是服務(wù)端不支持CORS;這也是fetch的特殊跨域請(qǐng)求方式;其對(duì)應(yīng)的response type為opaque。
針對(duì)跨域請(qǐng)求,cors模式是常見跨域請(qǐng)求實(shí)現(xiàn),但是fetch自帶的no-cors跨域請(qǐng)求模式則較為陌生,該模式有一個(gè)比較明顯的特點(diǎn):
該模式允許瀏覽器發(fā)送本次跨域請(qǐng)求,但是不能訪問響應(yīng)返回的內(nèi)容,這也是其response type為opaque透明的原因,如下圖:
呃,感覺這樣雖然解決能跨域問題,但是請(qǐng)求不到任何數(shù)據(jù),還是沒有卵用...
注意: cors 支持 三種content-type 不支持 application/json
application/x-www-form-urlencoded
multipart/form-data
text/plain
body:需要傳遞的參數(shù)
fetch請(qǐng)求默認(rèn)是不會(huì)攜帶cookie信息,如果想要攜帶,需要在手動(dòng)設(shè)置
fetch(url, { method: "POST", headers:{ "Content-type":"application/json"http:// 設(shè)置請(qǐng)求頭數(shù)據(jù)類型 }, credentials: "include" })
credentials: "include" 設(shè)置請(qǐng)求頭攜帶cookie信息
put請(qǐng)求fetch(url,{ method:"PUT", headers:{ "Content-type":"application/json"http:// 設(shè)置請(qǐng)求頭數(shù)據(jù)類型 }, body:data }) .then(res=>res.json()) .then(data=>console.log(data))delete請(qǐng)求
fetch(url,{ method:"DELETE", headers:{ "Content-type":"application/json"http:// 設(shè)置請(qǐng)求頭數(shù)據(jù)類型 }, body:data }) .then(res=>res.json()) .then(data=>console.log(data))
其實(shí),post,put,delete,這三個(gè)請(qǐng)求代碼上差不多,只是method中對(duì)應(yīng)不同的請(qǐng)求方法不同而已。
如下是自己封裝的fetch的API代碼 HTML頁面app.jsDocument
const url = "http://jsonplaceholder.typicode.com/users"; let easyHttp = new EasyHttp; // 請(qǐng)求數(shù)據(jù) easyHttp.get(url) .then(res=>console.log(res)) .catch(err=>console.log(err)) // 發(fā)送數(shù)據(jù) const data = { name:"Henry", username:"露絲", email:"[email protected]" }; // easyHttp.post(url,data) // .then(res=>console.log(res)) // .catch(err=>console.log(err)) // 修改數(shù)據(jù) // 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))easyhttp.js
/** * fetch 增刪改查 的API封裝 */ class EasyHttp{ // get 請(qǐng)求 get(url){ return new Promise((resolve,reject)=>{ fetch(url) .then(res=>res.json()) .then(data=>resolve(data)) .catch(err=>reject(err)) }) } // post 請(qǐng)求 post(url,data){ return new Promise((resolve,reject)=>{ fetch(url,{ method:"POST", headers:{ "Content-type":"application/json"http:// 設(shè)置請(qǐng)求頭數(shù)據(jù)類型 }, body:data }) .then(res=>res.json()) .then(data=>resolve(data)) .then(err=>reject(err)) }) } // put 請(qǐng)求修改數(shù)據(jù) put(url,data){ return new Promise((resolve,reject)=>{ fetch(url,{ method:"PUT", headers:{ "Content-type":"application/json"http:// 設(shè)置請(qǐng)求頭數(shù)據(jù)類型 }, body:data }) .then(res=>res.json()) .then(data=>resolve(data)) .then(err=>reject(err)) }) } // delete 刪除數(shù)據(jù) delete(url,data){ return new Promise((resolve,reject)=>{ fetch(url,{ method:"DELETE", headers:{ "Content-type":"application/json"http:// 設(shè)置請(qǐng)求頭數(shù)據(jù)類型 }, body:data }) .then(res=>res.json()) .then(data=>"刪除數(shù)據(jù)成功。。。") .then(err=>reject(err)) }) } }
源碼地址:戳一下
最后總結(jié)fetch和XMLHttpRequest相比,主要有以下優(yōu)點(diǎn):
語法簡(jiǎn)潔,更加語義化
基于標(biāo)準(zhǔn) Promise 實(shí)現(xiàn),支持 async/await
同構(gòu)方便,使用 isomorphic-fetch
參考文章 MDN Fetch API ECMAScript 6 入門 Fetch相比Ajax有什么優(yōu)勢(shì)? 【fetch跨域請(qǐng)求】cors文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93637.html
摘要:四請(qǐng)求常見數(shù)據(jù)格式接下來將介紹如何使用請(qǐng)求本地文本數(shù)據(jù),請(qǐng)求本地?cái)?shù)據(jù)以及請(qǐng)求網(wǎng)絡(luò)接口。請(qǐng)求網(wǎng)絡(luò)接口獲取中的數(shù)據(jù),做法與獲取本地的方法類似得到數(shù)據(jù)后,同樣要經(jīng)過處理 一 序言 在 傳統(tǒng)Ajax 時(shí)代,進(jìn)行 API 等網(wǎng)絡(luò)請(qǐng)求都是通過XMLHttpRequest或者封裝后的框架進(jìn)行網(wǎng)絡(luò)請(qǐng)求,然而配置和調(diào)用方式非?;靵y,對(duì)于剛?cè)腴T的新手并不友好。今天我們介紹的Fetch提供了一個(gè)更好的替代方...
摘要:四請(qǐng)求常見數(shù)據(jù)格式接下來將介紹如何使用請(qǐng)求本地文本數(shù)據(jù),請(qǐng)求本地?cái)?shù)據(jù)以及請(qǐng)求網(wǎng)絡(luò)接口。請(qǐng)求網(wǎng)絡(luò)接口獲取中的數(shù)據(jù),做法與獲取本地的方法類似得到數(shù)據(jù)后,同樣要經(jīng)過處理 一 序言 在 傳統(tǒng)Ajax 時(shí)代,進(jìn)行 API 等網(wǎng)絡(luò)請(qǐng)求都是通過XMLHttpRequest或者封裝后的框架進(jìn)行網(wǎng)絡(luò)請(qǐng)求,然而配置和調(diào)用方式非?;靵y,對(duì)于剛?cè)腴T的新手并不友好。今天我們介紹的Fetch提供了一個(gè)更好的替代方...
摘要:四請(qǐng)求常見數(shù)據(jù)格式接下來將介紹如何使用請(qǐng)求本地文本數(shù)據(jù),請(qǐng)求本地?cái)?shù)據(jù)以及請(qǐng)求網(wǎng)絡(luò)接口。請(qǐng)求網(wǎng)絡(luò)接口獲取中的數(shù)據(jù),做法與獲取本地的方法類似得到數(shù)據(jù)后,同樣要經(jīng)過處理 一 序言 在 傳統(tǒng)Ajax 時(shí)代,進(jìn)行 API 等網(wǎng)絡(luò)請(qǐng)求都是通過XMLHttpRequest或者封裝后的框架進(jìn)行網(wǎng)絡(luò)請(qǐng)求,然而配置和調(diào)用方式非常混亂,對(duì)于剛?cè)腴T的新手并不友好。今天我們介紹的Fetch提供了一個(gè)更好的替代方...
摘要:導(dǎo)讀全稱即異步與它最早在中被使用然后由推廣開來典型的代表應(yīng)用有以及現(xiàn)代網(wǎng)頁中幾乎無不歡前后端分離也正是建立在異步通信的基礎(chǔ)之上瀏覽器為做了什么現(xiàn)代瀏覽器中雖然幾乎全部支持但它們的技術(shù)方案卻分為兩種標(biāo)準(zhǔn)瀏覽器通過對(duì)象實(shí)現(xiàn)了的功能只需要通過一行 導(dǎo)讀 Ajax 全稱 Asynchronous JavaScript and XML, 即異步JS與XML. 它最早在IE5中被使用, 然后由Mo...
摘要:因?yàn)檎?qǐng)求是異步的,我們無法獲知請(qǐng)求的進(jìn)度和響應(yīng)狀態(tài),給我們提供了一個(gè)事件,我們可以通過監(jiān)聽這個(gè)時(shí)間來關(guān)注這種變化,所以下一步是注冊(cè)事件。請(qǐng)求還沒有被發(fā)送。方法已調(diào)用,請(qǐng)求已發(fā)送到服務(wù)器。到此,請(qǐng)求準(zhǔn)備完全完成。 上一篇單獨(dú)寫的是ajax跨域,這一篇就來詳細(xì)說一說ajax,ajax是現(xiàn)代web開發(fā)中必不可少的一部分內(nèi)容,非?;A(chǔ)也非常重要,這篇總結(jié)一下到目前為止我對(duì)ajax的理解。 什么...
閱讀 2012·2021-11-15 18:09
閱讀 903·2021-09-06 15:13
閱讀 2645·2021-08-23 09:43
閱讀 2026·2019-08-30 15:54
閱讀 2219·2019-08-30 13:56
閱讀 2486·2019-08-26 11:31
閱讀 3081·2019-08-26 10:56
閱讀 705·2019-08-26 10:28