# Fetch API 和 Axios
在發布 Fetch
API 之前,Axios
是流行的請求 HTTP 方法。
但是,現在大多數現代瀏覽器都內置了 Fetch
API,我們可以使用它來簡化 HTTP 請求,這在某些情況下使 Axios
變得多餘。
# Fetch API
Fetch
API 是用於在瀏覽器上發出 HTTP 請求的標準 API它是舊
XMLHttpRequest
constructor 進行請求的絕佳選擇它支持各種請求,包括
GET
,POST
,PUT
,PATCH
,DELETE
和OPTIONS
,這是大多數人所需要的使用 ES6 的 Promise 作回應,當用
then
後,接收到的第一個物件會為ReadableStream
,需要使用不同資料類型使用對應方法,才能正確取得資料物件
例如,我們可以寫
const res = await fetch('https://api.agify.io/?name=michael');
const data = await res.json();
2
在上面的程式碼中,我們從 API 發出了一個簡單的 GET
請求,然後使用 json()
方法將數據從 JSON 轉換為 JavaScript 對象。
另外,我們還可以使用 Fetch
API 處理其他格式的響應主體,包括 純文字 和 二進制數據(binary data)。
# 發送帶有 HTTP 標頭的請求
const headers = new Headers();
headers.append('Authorization', 'api_key');
const request = new Request(
'https://api.pexels.com/v1/curated?per_page=11&page=1',
{
method: 'GET',
headers,
mode: 'cors',
cache: 'default',
}
);
const res = await fetch(request);
const { photos } = await res.json();
2
3
4
5
6
7
8
9
10
11
12
13
在上面的程式碼中,我們使用了 Headers
constructor,該 constructor 用於將 requests headers 添加到 Fetch
API 請求中。再利用 append
方法將 Authorization
header 附加到請求。
對於跨域請求,我們必須將模式設置為 cors
。
# Post 請求
const body = JSON.stringify({ title: 'title', body: 'body' })
const request = new Request('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
mode: 'cors',
cache: 'default',
body
const res = await fetch(request);
const data = await res.json();
2
3
4
5
6
7
8
9
在上面的程式碼中,我們通過對 body
對象進行 字符串化 然後通過 POST
請求發送來發出請求。
# ReadableStream
Fetch API 的 Response 物件中的 body
屬性提供了一個 ReadableStream
的實體,這個階段無法直接讀取資料內容,而 ReadableStream
物件中可用以下對應的方法來取得資料:
- arrayBuffer()
- blob()
- formData()
- json()
- text()
# json()
fetch('https://randomuser.me/api/', {})
.then((response) => {
// 這裡會得到一個 ReadableStream 的物件
console.log(response);
// 可以透過 blob(), json(), text() 轉成可用的資訊
return response.json();
})
.then((jsonData) => {
console.log(jsonData);
})
.catch((err) => {
console.log('錯誤:', err);
});
2
3
4
5
6
7
8
9
10
11
12
13
# blob()
可以將資料轉為 blob
物件,像是圖片就可以做這樣的轉換 (這裡的圖片並非指圖片路徑,而是圖片檔案本身)。
來實作一個下載圖片範例:
fetch(url)
.then((response) => {
return response.blob();
})
.then((imageBlob) => {
// createObjectURL 可以將 blob 物件轉為網址
const href = URL.createObjectURL(blob);
const link = document.createElement('a');
document.body.appendChild(link);
link.href = href;
link.download = 'photo.jpeg';
link.click();
document.body.removeChild(link);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
# Axios
# Get 請求
我們使用 axios.get
方法來發出請求。再將響應數據分配給一個對象。
const { data } = await axios.get('https://api.agify.io/?name=michael');
# 發送帶有 HTTP 標頭的請求
const {
data: { photos },
} = await axios({
url: 'https://api.pexels.com/v1/curated?per_page=11&page=1',
headers: {
Authorization: 'api_key',
},
});
2
3
4
5
6
7
8
在上面的程式碼中,我們使用帶有 axios
方法的 Pexels
API 密鑰發出了 GET
請求,該請求可用於發出任何類型的請求。
如果未指定請求動詞,預設將是 GET
請求。
由於不必使用 Headers
constructor 創建對象,因此程式碼短了一點。
# 多個請求中設置相同的標頭
可以使用請求攔截器(request interceptor) 為所有請求設置 header 或其他配置
const axios = require('axios');
// 遞給 axios.interceptors.request.use 的第一個參數是用於修改所有請求的請求配置的函式
// 第二個參數是一個錯誤處理程序,用於處理所有請求的錯誤
axios.interceptors.request.use(
(config) => {
return {
...config,
headers: {
Authorization: 'api_key',
},
};
},
(error) => Promise.reject(error)
);
const {
data: { photos },
} = await axios({
url: 'https://api.pexels.com/v1/curated?per_page=11&page=1',
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Post 請求
我們可以使用 axios.post
方法
// 在第二個參數中添加請求參數
// 通過從響應結果中獲取 data 屬性來獲取響應數據
const { data } = await axios.post(
'https://jsonplaceholder.typicode.com/posts',
{ title: 'title', body: 'body' }
);
2
3
4
5
6
# 比較
Fetch
API 和 Axios
在許多方面都相似。 它們都可以輕鬆應用到 VueJS
中,並且從本質上來說,它們都可以完成工作。
如果要處理 多個請求,則會發現 Fetch
所要編寫的代碼多於 Axios
,即使考慮到所需的設置也是如此。
因此,對於簡單的請求,Fetch
API 和 Axios
完全相同。但是,對於更 複雜 的請求,Axios
更好,因為它允許在相同的配置下,發送多個請求。
# 參考
Requests in VueJS: Fetch API and Axios — A Comparison (opens new window)