導(dǎo)讀
傳遞信息到服務(wù)器,從服務(wù)器獲取信息弟断,是前端發(fā)展的重中之重,尤其是現(xiàn)在前后端分離的大前提下趴生,前后端的數(shù)據(jù)交互是前端的必修科目了阀趴。從很久之前到現(xiàn)在,ajax都是每個(gè)前端入行者必須技能苍匆。當(dāng)然為了便于開發(fā)者刘急, 各種三方工具將ajax包裝,然后給開發(fā)者使用浸踩,jquery叔汁、axios等等。這都不是今天的重點(diǎn)检碗, 今天要說(shuō)一個(gè)JavaScript原生的獲取資源接口 Fetch API据块, 雖然各大瀏覽器支持率不高,但是這樣的一個(gè)概念確實(shí)值得了解學(xué)習(xí)折剃,并且現(xiàn)在我們可以通過(guò)polyfill來(lái)實(shí)現(xiàn)不同瀏覽器的兼容性問(wèn)題
Fetch
先來(lái)看看各個(gè)瀏覽器對(duì)fetch的原生支持情況另假,可以看到支持性并不是很高,safari在10.1 之后才支持怕犁,ios更是10.3之后才支持边篮,IE完全不支持。當(dāng)然新技術(shù)的發(fā)展總會(huì)經(jīng)歷這個(gè)過(guò)程奏甫。不過(guò)戈轿,想提前嘗嘗鮮也是可以的我們可以使用 polyfill
聲明:以下的所有代碼測(cè)試都是基于 Chrome 實(shí)現(xiàn)
廢話不多說(shuō),
fetch 返回的是一個(gè)Promise扶檐,我們先來(lái)看一個(gè)基本的 fetch 結(jié)構(gòu)
fetch(url, option).then( res => {
//do something
}).catch(err => {
//do something
})
fetch 的url 參數(shù)是必須的凶杖,option參數(shù)可選
以上就是整個(gè)的請(qǐng)求以及處理過(guò)程胁艰, 驚不驚喜款筑,意不意外智蝠,沒錯(cuò)就是這么簡(jiǎn)單清晰明了,沒有原生ajax的那些 XMLHttpRequest
bulabula 一大堆奈梳。也不需要再額外引入一個(gè)jquery包(當(dāng)然項(xiàng)目中使用到的話除外)杈湾。當(dāng)然因?yàn)閒etch的返回值是一個(gè)Promise, 不需要再去使用回調(diào)函數(shù)從而有效避免回調(diào)地獄攘须。
當(dāng)然漆撞,fetch不止于此,我們的需求也不止于此于宙,我們可能需要post請(qǐng)求浮驳,可能需要跨域請(qǐng)求,控制從服務(wù)器獲取的信息的格式(json捞魁、string至会、blob等),此時(shí)谱俭,便需要設(shè)置參數(shù)信息奉件,對(duì)返回信息進(jìn)行處理。
option
來(lái)看看fetch的可選參數(shù)option的可選值昆著,fetch默認(rèn)是get方法县貌,也可以在option中設(shè)置為其他方法
- method:get | post 等方法
- headers:任何你想加到請(qǐng)求中的頭,可以是對(duì)象字面量的方式也可以是通過(guò) Headers
- body:發(fā)送給服務(wù)器的信息凑懂, 可以是JSON, ufferSource, FormData, URLSearchParams, 或 USVString煤痕。注意get和HEAD請(qǐng)求沒有body
- mode:請(qǐng)求模式, 可選值為 cors, no-cors, same-origin, 或 navigate接谨,cors-with-forced-preflight杭攻。默認(rèn)值應(yīng)該為 cors。但在Chrome中疤坝,Chrome 47 之前的版本默認(rèn)值為 no-cors 兆解,自Chrome 47起,默認(rèn)值為same-origin跑揉。--MDN Request
- credentials:在請(qǐng)求中是否需要憑據(jù)锅睛。在請(qǐng)求數(shù)據(jù)中根據(jù)是否需要攜帶Cookie 來(lái)設(shè)置其值,可選值為omit(在請(qǐng)求中不懈怠認(rèn)證憑據(jù)(Cookie)), same-origin(在同原站點(diǎn)下包含憑據(jù)), 或 include(對(duì)所有網(wǎng)站包含認(rèn)證憑據(jù))
- cache:如何處理緩存历谍,可取值有 default | no-store | no-cache | reload | force-cache | only-if-cached
- redirect:對(duì)重定向的處理现拒,可取值 follow, error, redirect
- referrer:一個(gè)指定了no-referrer, client, 或一個(gè) URL的 USVString 。默認(rèn)值是client.
- integrity: 包括請(qǐng)求的 subresource integrity 值 (e.g., sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=).
mode
mode 參數(shù)便于 CORS望侈, 設(shè)置不同的值可以使在不同的請(qǐng)求方式下印蔬,使得請(qǐng)求有效。
- cors:在同域和帶有CORS響應(yīng)頭的跨域下可以請(qǐng)求成功
- no-cors:常用于在跨域不帶CORS場(chǎng)景下脱衙, 此時(shí)請(qǐng)求發(fā)出并且會(huì)有響應(yīng)侥猬,但是此時(shí)type為“opaque”例驹, status為0 ,js獲取不到返回?cái)?shù)據(jù)退唠。
- same-origin:在同域下請(qǐng)求
- cors-with-forced-preflight:在請(qǐng)求前進(jìn)行preflight 檢查
fetch("https://api.github.com/users/mzabriskie", {mode: "no-cors"}).then(response => {
return response;
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
執(zhí)行以上代碼返回
fetch("https://api.github.com/users/mzabriskie", {mode: "cors"}).then(response => {
return response;
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
以上代碼返回
headers
該參數(shù)的值可以為對(duì)象字面量
headers: {
"Content-Type": "application/json"
}
也可以創(chuàng)建 Headers 對(duì)象鹃锈,通過(guò)append() 和delete() 等方法對(duì)其進(jìn)行操作,
var headers = new Headers();
headers.append( "Content-Type", "application/json");
fetch(url, {
method: post,
headers: headers,
body: {
name: "jack"
}
})
Request
Fetch 提供了對(duì) Request 和 Response (以及其他與網(wǎng)絡(luò)請(qǐng)求有關(guān)的)對(duì)象的通用定義瞧预。所以在一個(gè)Fetch請(qǐng)求中屎债,完全可以只使用Request 和 Response兩個(gè)對(duì)象,通過(guò)Request 設(shè)置參數(shù)垢油,通過(guò)Response 對(duì)返回值進(jìn)行處理盆驹。
一個(gè)Fetch還可以寫成以下形式
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'image/jpeg');
var option = { method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default' };
var myRequest = new Request('https://api.github.com/users/mzabriskie',option);
fetch(myRequest).then(function(response) {
...
});
參數(shù)設(shè)置如 option 下介紹
Response
Fetch API 的Response接口呈現(xiàn)了對(duì)一次請(qǐng)求的響應(yīng)數(shù)據(jù)
其包含一次請(qǐng)求的響應(yīng)信息,響應(yīng)狀態(tài)等滩愁。
包含的一些常用屬性(只讀)
- url:包含請(qǐng)求地址url
- status:響應(yīng)狀態(tài)碼(200成功)
- ok:一個(gè)布爾值標(biāo)識(shí)請(qǐng)求成功或失敗
- statusText:包含與狀態(tài)碼對(duì)應(yīng)的狀態(tài)信息
- headers:包含于請(qǐng)求關(guān)聯(lián)的Headers對(duì)象
****方法****
- clone(): 創(chuàng)建Response對(duì)象的克隆
Response可以使用以下方法召娜,對(duì)響應(yīng)數(shù)據(jù)進(jìn)行處理
arrayBuffer()、blob()惊楼、formData()玖瘸、json()、text()等
以下為使用json() 方法返回的數(shù)據(jù)信息
fetch("https://api.github.com/users/mzabriskie", {mode: "no-cors"}).then(response => {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
檢測(cè)請(qǐng)求是否成功
同XMLHttpResponse一樣檀咙,請(qǐng)求發(fā)出雅倒,服務(wù)器發(fā)出返回碼,除了407以外弧可,其不會(huì)進(jìn)入錯(cuò)誤捕捉蔑匣。也就是說(shuō)除了網(wǎng)絡(luò)故障或者跨域請(qǐng)求被拒絕等請(qǐng)求失敗的情況,fetch() 的Promise是不會(huì) reject的棕诵,所以為了請(qǐng)求能按照我們的預(yù)期實(shí)現(xiàn)裁良,我們必須加一個(gè)判斷,判斷請(qǐng)求是否成功并返回了我們想要的數(shù)據(jù)校套。我們當(dāng)然可以像 XMLHttpResponse 一樣對(duì)響應(yīng)的狀態(tài)碼進(jìn)行判斷价脾,不過(guò)我們還有選擇,對(duì)response.ok 這個(gè)布爾值入手笛匙。
細(xì)心的同學(xué)可能從之前的截圖中看到侨把,在請(qǐng)求成功和失敗的情況下,屬性 ok 的值 分別為true 和false 這里就不贅余天價(jià)截圖了妹孙,上代碼
fetch("https://api.github.com/users/mzabriskie", {mode: "cors"}).then(response => {
if(response.ok) {
response.json().then(data => {
console.log(data);
});
} else {
console.log("請(qǐng)求不成功秋柄,狀態(tài)碼為", response.status);
}
}).catch(function(e) {
console.log("Oops, error");
});
致此, 一個(gè) fetch 的簡(jiǎn)單請(qǐng)求便完成了蠢正,但是fetch功能遠(yuǎn)不止這些
fetch 與 ES7的async/await 搭配使用等等骇笔,路很長(zhǎng)一步一腳印
參考鏈接
Fetch API - Web API 接口 | MDN
Request - Web API 接口 | MDN
Headers - Web API 接口 | MDN
Response - Web API 接口 | MDN
Body - Web APIs | MDN