自從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
由於網頁為繁體內容,術語描述和話術與我們有差異的問題,筆者在保證不改變原意的基礎上做了調整,並在此基礎上進行了錯誤校正,如發現問題,歡迎你的指正
小結
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
更多精彩內容,請
關注“前端達人”公眾號閱讀更多 前端達人 的文章