自從Fetch API 問世以來,我們就能使用漂亮的語法發(fā)送HTTP Request 或取后臺接口數(shù)據(jù),這篇文章將會分享我自己常用的Fetch方法( GET、POST、搭配await 或promise.all...等) ,隨著瀏覽器的普遍支持,也就不太需要使用XMLHttpRequest 或jQuery AJAX,我們的代碼看起來也就更加簡潔干凈啰~
Fetch 基本用法
fetch()方法,包含了需要fetch 的網(wǎng)址和對應(yīng)的屬性設(shè)定( 例如method、headers、mode、body...等,最基本的寫法屬性不一定要填),執(zhí)行之后會送出Request,如果得到回應(yīng)就會回傳帶有Response 的Promise 內(nèi)容,使用then 將回傳值傳遞下去。
fetch('網(wǎng)址') .then(function(response) { // 處理 response }).catch(function(err) { // 錯誤處理 });
舉例來說,通過天氣數(shù)據(jù)開放平臺可以取得許多氣象資料(例如阿里云的API開放平臺),下面的示例獲取北京的當(dāng)日氣溫,因為結(jié)果返回為json格式,所以在fetch取得數(shù)據(jù)之后,通過json()的方法處理數(shù)據(jù),接著傳遞到下一層,就能顯示出「北京市的當(dāng)日氣溫」。
fetch('天氣數(shù)據(jù)開放平臺網(wǎng)址') .then(res => { return res.json(); }).then(result => { let city = result.cwbopendata.location[14].parameter[0].parameterValue; let temp = result.cwbopendata.location[14].weatherElement[3].elementValue.value; console.log(`${city}的當(dāng)前氣溫 ${temp} 攝氏度`); // 得到 北京市的氣溫 29.30攝氏度 });
Fetch 的 Request 屬性
以下列出Fetch常用的的Request屬性。(更多屬性請參考fetch Request )

Fetch 的Response 屬性
以下列出Fetch常用的Response屬性。(更多屬性和方法請參考fetch Response )

Fetch 的Response 方法
以下列出Fetch常用的Response方法。(更多屬性和方法請參考fetch Response )

Fetch 的Get 用法
Get 是Fetch 最簡單的方法,使用Get 必須要將fetch 第二個參數(shù)里的method 設(shè)定為get,如果遇到跨域問題,就搭配其他屬性例如mode、credentials 來進行細部設(shè)定( 但針對非跨域的就沒用了),下方的示例我做了一個簡單的后端請求,通過fetch 傳遞姓名和年紀的參數(shù),就會看到后端回應(yīng)一串文字。
const name = 'oxxo'; const age = 18; const uri = `https://網(wǎng)址/exec?name=${name}&age=${age}`; fetch(uri, {method:'GET'}) .then(res => { return res.text(); // 使用 text() 可以得到純文字 String }).then(result => { console.log(result); // 得到「你的名字是:oxxo,年紀:18 歲?!?});
Fetch 的Post 用法
使用POST方法可以搭配body屬性設(shè)定傳遞參數(shù),比如我的接口地址,可以接收name和age所組成的JSON請求,當(dāng)網(wǎng)址接收到要求后,就會回應(yīng)一個json對象,需要注意的是,如果是傳遞「中文」可能會出現(xiàn)亂碼,這時可以使用encodeURI來做轉(zhuǎn)碼,且要通過JSON.stringify來轉(zhuǎn)換成string方式傳遞。
const uri = '網(wǎng)址'; fetch(uri, { method:'POST', body:encodeURI(JSON.stringify({ name:'oxxo', age:18 })), headers: { 'Content-Type': 'Application/x-www-form-urlencoded; charset=utf-8' } }) .then(res => { return res.json(); // 使用 json() 可以得到 json 對象 }).then(result => { console.log(result); // 得到 {name: "oxxo", age: 18, text: "你的名字是 oxxo,年紀18歲~"} });
Fetch 搭配async、await、promise.all
過去在XMLHttpRequest 或jQuery AJAX 的全盛時期,如果要確保每個GET 或POST 的要求,都要按照指定的順序進行,往往會用上一連串的callback 輔助,但是當(dāng)callback 越來越多,代碼也就越來越難管理,然而fetch 返回的是一個Promise,我們也就能直接利用await 或promise.all 的作法,輕松掌握同步與非同步之間的轉(zhuǎn)換。
下方的例子是一個非同步的示例,因為沒有進行任何的同步處理,所以執(zhí)行之后,會先出現(xiàn)hello的文字,接著才是通過fetch 得到的結(jié)果。
const postURL = (name,age) => { const uri = 'https://網(wǎng)址; return fetch(uri, { method:'POST', body:encodeURI(JSON.stringify({ name:name, age:age })), headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' } }) .then(res => { return res.json(); }).then(result =>{ console.log(result); }); }; postURL('oxxo',18); console.log('hello!!!'); postURL('tom',18);
因為fetch 的特性,可以改成async 和await 的寫法,執(zhí)行后也就能按照我們要的順序進行。
async function(){ // 設(shè)定為 async const postURL = (name,age) => { const uri = 'https://網(wǎng)址'; return fetch(uri, { method:'POST', body:encodeURI(JSON.stringify({ name:name, age:age })), headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' } }) .then(res => { return res.json(); }).then(result =>{ console.log(result); }); }; await postURL('oxxo',18); // 使用 await console.log('hello!!!'); await postURL('tom',18); // 使用 await }();
最后那段await 的代碼,也可以改成promise.all 的方法,就會先fetch,然后再出現(xiàn)hello的文字,不過也因為promise.all無法保證其載入順序,就可能會發(fā)生tom 在oxxo之前出現(xiàn)的狀況呦。
await Promise.all([postURL('oxxo',18), postURL('tom',18)]); console.log('hello!!!');
兼容性
說了這么多,你一定關(guān)心這個API的兼容性,現(xiàn)代瀏覽器大部分還是支持的,可以放心使用,如下圖所示:

文章來源:https://www.oxxostudio.tw/articles/201908/js-fetch.html
原文作者:oxxostudio
由于網(wǎng)頁為繁體內(nèi)容,術(shù)語描述和話術(shù)與我們有差異的問題,筆者在保證不改變原意的基礎(chǔ)上做了調(diào)整,并在此基礎(chǔ)上進行了錯誤校正,如發(fā)現(xiàn)問題,歡迎你的指正
小結(jié)
Fetch API 的神奇,簡化了許多原本較為復(fù)雜的用法,也讓項目代碼寫起來更加干凈易讀好維護。
更多參考資源:
MDN:Using Fetch
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
AJAX 與Fetch API
https://eyesofkids.gitbooks.io/JAVAscript-start-from-es6/content/part4/ajax_fetch.html
更多精彩內(nèi)容,請關(guān)注“前端達人”公眾號