自從Fetch API 問世以來,我們就能使用漂亮的語法發送HTTP Request 或取后臺接口數據,這篇文章將會分享我自己常用的Fetch方法( GET、POST、搭配await 或promise.all...等) ,隨著瀏覽器的普遍支持,也就不太需要使用XMLHttpRequest 或jQuery AJAX,我們的代碼看起來也就更加簡潔干凈啰~
Fetch 基本用法
fetch()方法,包含了需要fetch 的網址和對應的屬性設定( 例如method、headers、mode、body...等,最基本的寫法屬性不一定要填),執行之后會送出Request,如果得到回應就會回傳帶有Response 的Promise 內容,使用then 將回傳值傳遞下去。
fetch('網址') .then(function(response) { // 處理 response }).catch(function(err) { // 錯誤處理 });
舉例來說,通過天氣數據開放平臺可以取得許多氣象資料(例如阿里云的API開放平臺),下面的示例獲取北京的當日氣溫,因為結果返回為json格式,所以在fetch取得數據之后,通過json()的方法處理數據,接著傳遞到下一層,就能顯示出「北京市的當日氣溫」。
fetch('天氣數據開放平臺網址') .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}的當前氣溫 ${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 第二個參數里的method 設定為get,如果遇到跨域問題,就搭配其他屬性例如mode、credentials 來進行細部設定( 但針對非跨域的就沒用了),下方的示例我做了一個簡單的后端請求,通過fetch 傳遞姓名和年紀的參數,就會看到后端回應一串文字。
const name = 'oxxo'; const age = 18; const uri = `https://網址/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屬性設定傳遞參數,比如我的接口地址,可以接收name和age所組成的JSON請求,當網址接收到要求后,就會回應一個json對象,需要注意的是,如果是傳遞「中文」可能會出現亂碼,這時可以使用encodeURI來做轉碼,且要通過JSON.stringify來轉換成string方式傳遞。
const uri = '網址'; 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 輔助,但是當callback 越來越多,代碼也就越來越難管理,然而fetch 返回的是一個Promise,我們也就能直接利用await 或promise.all 的作法,輕松掌握同步與非同步之間的轉換。
下方的例子是一個非同步的示例,因為沒有進行任何的同步處理,所以執行之后,會先出現hello的文字,接著才是通過fetch 得到的結果。
const postURL = (name,age) => { const uri = 'https://網址; 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 的寫法,執行后也就能按照我們要的順序進行。
async function(){ // 設定為 async const postURL = (name,age) => { const uri = 'https://網址'; 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,然后再出現hello的文字,不過也因為promise.all無法保證其載入順序,就可能會發生tom 在oxxo之前出現的狀況呦。
await Promise.all([postURL('oxxo',18), postURL('tom',18)]); console.log('hello!!!');
兼容性
說了這么多,你一定關心這個API的兼容性,現代瀏覽器大部分還是支持的,可以放心使用,如下圖所示:

文章來源:https://www.oxxostudio.tw/articles/201908/js-fetch.html
原文作者:oxxostudio
由于網頁為繁體內容,術語描述和話術與我們有差異的問題,筆者在保證不改變原意的基礎上做了調整,并在此基礎上進行了錯誤校正,如發現問題,歡迎你的指正
小結
Fetch API 的神奇,簡化了許多原本較為復雜的用法,也讓項目代碼寫起來更加干凈易讀好維護。
更多參考資源:
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
更多精彩內容,請關注“前端達人”公眾號