想知道 Axios 是什麼?這篇教學將帶你深入了解這個最受歡迎的 JavaScript HTTP 客戶端,從基本用法到錯誤處理、請求攔截、取消請求等進階功能,幫助你有效管理 Web API 串接工作。
什麼是 Axios?
Axios 是一個基於 Promise 的 HTTP 客戶端,可用於瀏覽器和 Node.js 環境。它是同構的(isomorphic),意味著它可以在瀏覽器和 Node.js 中使用相同的代碼庫。在服務器端,它使用原生 Node.js 的 http
模組,而在客戶端(瀏覽器)中使用 XMLHttpRequests。Axios 的設計理念是提供一個簡單而統一的 API,使開發人員能夠輕鬆處理複雜的 HTTP 請求。
Axios 與原生 Fetch API 的比較
在了解 Axios 的優勢之前,我們先將其與瀏覽器原生的 Fetch API 進行比較:
特性 | Fetch API | Axios 庫 |
---|---|---|
起源 | 原生 JavaScript API | 第三方庫 |
安裝 | 瀏覽器和 Node.js v18+ 原生可用 | 需要 npm 安裝 |
JSON 解析 | 手動(需要使用 .json()) | 自動 |
錯誤處理 | 最小(僅網絡錯誤) | 全面 |
請求攔截器 | 不可用 | 可用 |
請求取消 | 需要 AbortController | 內置方法 |
響應轉換 | 手動 | 自動 |
平台支持 | 曾經僅瀏覽器,現在 Node.js v18+ 可用 | 瀏覽器和 Node.js |
讓我們通過一個簡單的例子來比較這兩種方法的語法差異。以下是使用 Axios 發送 POST 請求的方式:
// axios
const url = "https://jsonplaceholder.typicode.com/posts";
const data = {
a: 10,
b: 20,
};
async function postData() {
try {
const response = await axios.post(url, data, {
headers: {
Accept: "application/json",
"Content-Type": "application/json;charset=UTF-8",
},
});
console.log(response.data);
} catch (error) {
console.error("Error posting data:", error);
}
}
postData();
而使用 Fetch API 完成相同任務的代碼如下:
// fetch()
const url = "https://jsonplaceholder.typicode.com/todos";
const options = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json;charset=UTF-8",
},
body: JSON.stringify({
a: 10,
b: 20,
}),
};
fetch(url, options)
.then((response) => response.json())
.then((data) => {
console.log(data);
});
從這個例子中可以看出,Axios 提供了更簡潔的 API,並且自動處理了 JSON 轉換。
如何開始使用 Axios
安裝 Axios
你可以通過多種方式將 Axios 添加到你的項目中:
使用 npm:
$ npm install axios
使用 yarn:
$ yarn add axios
或者通過 CDN 直接在 HTML 中引入:
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
Axios 的核心優勢
1. 自動數據轉換
Axios 能自動將請求數據轉換為 JSON,以及將響應數據從 JSON 轉換為 JavaScript 對象。這消除了手動調用 JSON.stringify()
和 response.json()
的需要,使代碼更加簡潔。
2. 全面的錯誤處理
與 Fetch API 不同,Axios 會自動對非 2xx 狀態碼拋出錯誤,使錯誤處理更為全面。這意味著你可以在 .catch()
中捕獲服務器端錯誤,而不需要手動檢查狀態碼。
axios
.get("https://api.example.com/data")
.then((response) => {
console.log(response.data);
})
.catch((error) => {
if (error.response) {
// 服務器回應了非 2xx 狀態碼
console.error("Server responded with:", error.response.status);
} else if (error.request) {
// 請求已發出但沒有收到回應
console.error("No response received");
} else {
// 發生了一些設置請求時的錯誤
console.error("Error:", error.message);
}
});
3. 請求和響應攔截器
Axios 提供了攔截器功能,允許在請求被發送到服務器之前或響應被傳遞給 .then()
或 .catch()
之前攔截並修改它們。這對於實現全局身份驗證、錯誤處理或日誌記錄非常有用。
// 添加請求攔截器
axios.interceptors.request.use(
(config) => {
// 在發送請求之前做些什麼
config.headers.Authorization = `Bearer ${localStorage.getItem("token")}`;
return config;
},
(error) => {
// 對請求錯誤做些什麼
return Promise.reject(error);
}
);
// 添加響應攔截器
axios.interceptors.response.use(
(response) => {
// 對響應數據做些什麼
return response;
},
(error) => {
// 對響應錯誤做些什麼
if (error.response && error.response.status === 401) {
// 處理未授權錯誤
}
return Promise.reject(error);
}
);
4. 請求取消
Axios 提供了內置的請求取消功能,使用起來比 Fetch API 的 AbortController 更加直觀。這在用戶導航離開頁面或搜索條件變更時特別有用。
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios
.get("/user/12345", {
cancelToken: source.token,
})
.catch(function (thrown) {
if (axios.isCancel(thrown)) {
console.log("Request canceled", thrown.message);
} else {
// 處理錯誤
}
});
// 取消請求(message 參數是可選的)
source.cancel("Operation canceled by the user.");
5. 請求超時設置
Axios 允許為請求設置超時時間,以防止請求長時間掛起。這是處理不穩定網絡或不響應服務器的有效方法。
axios
.get("/user/12345", {
timeout: 5000, // 5 秒後超時
})
.then((response) => console.log(response))
.catch((error) => console.error("Request timed out"));
6. 上傳和下載進度追踪
Axios 支持監控上傳和下載進度,這對於文件上傳和下載功能非常有用。
axios
.get("https://api.example.com/content.txt", {
onDownloadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(`下載進度:${percentCompleted}%`);
},
})
.then((response) => console.log(response.data));
7. 實例創建和全局配置
通過 axios.create()
,你可以創建具有自定義配置的 Axios 實例,簡化管理多個 API 端點或不同服務的請求。這種方法使代碼更加模塊化和可維護。
// 為不同的 API 端點創建不同的實例
const userAPI = axios.create({
baseURL: "https://api.example.com/users",
timeout: 3000,
headers: { Authorization: "Bearer user-token" },
});
const productAPI = axios.create({
baseURL: "https://api.example.com/products",
timeout: 5000,
headers: { Authorization: "Bearer product-token" },
});
// 使用這些實例
userAPI.get("/profile").then((response) => console.log(response.data));
productAPI.get("/list").then((response) => console.log(response.data));
8. XSRF 保護
Axios 內置了對 XSRF(跨站請求偽造)的保護功能,這是 Web 應用程序安全的一個重要方面。
// 在實例配置中啟用 XSRF 保護
const instance = axios.create({
xsrfCookieName: "XSRF-TOKEN",
xsrfHeaderName: "X-XSRF-TOKEN",
});
最適合使用 Axios 的場景
根據項目需求,以下是一些最適合使用 Axios 的場景:
- 大規模 API 調用:Axios 的流、攔截器和超時功能使其成為複雜應用的理想選擇。
- 需要重試邏輯和容錯能力:Axios 對非 2xx 錯誤會自動拋出異常,並有內置的超時功能。
- 文件上傳/下載:Axios 提供內置的進度事件跟踪。
- 構建可重用的 HTTP 工具:Axios 的靈活性和內置功能使其成為構建 HTTP 工具庫的理想選擇。
- 認證請求和令牌管理:Axios 的攔截器使管理身份驗證更加簡單。
基本使用示例
以下是一些基本的使用示例,展示了 Axios 的強大功能:
- 簡單的 GET 請求:
axios
.get("https://jsonplaceholder.typicode.com/posts")
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error("Error fetching data:", error);
});
- 使用 async/await:
async function fetchData() {
try {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/posts"
);
console.log(response.data);
} catch (error) {
console.error("Error fetching data:", error);
}
}
fetchData();
結論
Axios 作為一個功能豐富的 HTTP 客戶端庫,為現代 Web 開發提供了許多優勢。從自動數據轉換到請求攔截器,從錯誤處理到請求取消,Axios 都提供了簡單而強大的解決方案。雖然原生 Fetch API 在近年來得到了顯著改進,但 Axios 仍然在某些場景下提供了更好的開發體驗和更豐富的功能集。
對於需要進行複雜 API 交互的項目,尤其是那些需要統一錯誤處理、請求攔截或上傳/下載進度跟踪的項目,Axios 是一個值得考慮的選擇。它的簡潔 API 和強大功能使其成為許多開發者的首選工具,能夠顯著提高開發效率和代碼質量。
結合項目需求選擇合適的 HTTP 客戶端是明智的。對於簡單的客戶端應用,原生 Fetch API 可能已經足夠;但對於更複雜的應用場景,Axios 提供的額外功能和便利性將大大簡化你的開發工作。