目錄
- Axios 介紹
- 攔截器特性
- 1. 統一添加 Token(請求攔截器)
- 2. 處理 401 未授權(響應攔截器)
- 3. 統一處理錯誤信息(響應攔截器)
- 4. 請求 Loading 狀態管理
- 5. 自動重試請求(如 429 過載)
- 6. 數據格式轉換(響應攔截器)
- 7. 記錄請求日志(請求攔截器 + 響應攔截器)
- 總結
- 結論
Axios 介紹
Axios 是基于 XMLHttpRequest(XHR) 和 Promise 進行封裝的 HTTP 客戶端。
它的核心實現依賴于以下技術:
-
XMLHttpRequest(XHR)
- 在瀏覽器環境下,Axios 使用
XMLHttpRequest
發送 HTTP 請求,并基于它進行封裝,提供更簡潔的 API 和更好的錯誤處理機制。 - 例如,它支持請求和響應的攔截器、超時設置、請求取消等功能,而這些都需要額外的封裝才能在
XMLHttpRequest
中實現。
- 在瀏覽器環境下,Axios 使用
-
Node.js 的 http 模塊
- 在 Node.js 環境下,Axios 使用
http
或https
模塊代替XMLHttpRequest
發送 HTTP 請求,從而實現跨環境的兼容性。
- 在 Node.js 環境下,Axios 使用
-
Promise
- Axios 的 API 是基于
Promise
設計的,所有請求都會返回一個Promise
,支持async/await
,比傳統的XMLHttpRequest
更加方便。
- Axios 的 API 是基于
-
攔截器(Interceptors)
- 通過
request
和response
攔截器,Axios 允許在請求或響應到達應用程序之前,對其進行修改,比如添加請求頭、處理錯誤、全局 loading 等。
- 通過
-
取消請求(Cancel Token)
- 依賴
AbortController
或者CancelToken
(Axios 0.x 版本提供),可以在特定條件下取消未完成的 HTTP 請求。
- 依賴
-
自動 JSON 解析
- Axios 默認會將 JSON 響應數據自動解析成 JavaScript 對象,而
XMLHttpRequest
需要手動解析。
- Axios 默認會將 JSON 響應數據自動解析成 JavaScript 對象,而
-
并發請求管理
- 通過
axios.all()
和axios.spread()
,支持并行發送多個請求,并在所有請求完成后進行處理。
- 通過
總結來說,Axios 的底層實現主要基于 XMLHttpRequest(瀏覽器端)或 Node.js http 模塊(服務端),同時結合 Promise、攔截器、取消請求等高級特性,提供了比原生 API 更易用的 HTTP 請求功能。
攔截器特性
Axios 攔截器(Interceptors)可以在請求發送前或響應返回后進行處理,常用于全局請求配置、錯誤處理、權限校驗、自動重試等場景。以下是幾個實際應用示例:
1. 統一添加 Token(請求攔截器)
場景:
需要在所有請求的 headers
中添加 Authorization
頭部,例如 JWT Token。
import axios from "axios";// 創建 axios 實例
const api = axios.create({baseURL: "https://api.example.com",timeout: 5000,
});// 請求攔截器
api.interceptors.request.use(config => {const token = localStorage.getItem("token"); // 從本地存儲獲取 tokenif (token) {config.headers.Authorization = `Bearer ${token}`; // 設置 Authorization 頭部}return config;},error => Promise.reject(error)
);// 使用 axios 實例
api.get("/user/profile").then(response => console.log(response.data));
📌 效果:
- 所有請求都會自動附帶
Authorization
頭部,避免手動在每個請求中添加。
2. 處理 401 未授權(響應攔截器)
場景:
當后端返回 401 Unauthorized
,表示 Token 失效,應該自動跳轉到登錄頁。
api.interceptors.response.use(response => response,error => {if (error.response?.status === 401) {console.error("身份認證失敗,跳轉到登錄頁...");window.location.href = "/login"; // 重定向到登錄頁面}return Promise.reject(error);}
);
📌 效果:
- 如果請求返回
401
,用戶會被自動跳轉到登錄頁,而不會繼續執行后續邏輯。
3. 統一處理錯誤信息(響應攔截器)
場景:
后端返回錯誤時,攔截器可以解析 error.response.data
,并彈出錯誤提示。
import { message } from "antd"; // 適用于 Ant Design 的 message 組件api.interceptors.response.use(response => response,error => {if (error.response) {const { status, data } = error.response;const errorMsg = data.message || "服務器錯誤";message.error(`請求失敗 (${status}): ${errorMsg}`);} else {message.error("網絡異常,請檢查你的連接");}return Promise.reject(error);}
);
📌 效果:
- 400、500 等錯誤時,自動彈出友好的錯誤提示。
4. 請求 Loading 狀態管理
場景:
在請求發起時顯示 Loading 狀態,請求結束后自動隱藏。
import { message } from "antd";let requestCount = 0;function showLoading() {if (requestCount === 0) {message.loading("加載中...", 0);}requestCount++;
}function hideLoading() {requestCount--;if (requestCount === 0) {message.destroy(); // 關閉 loading}
}// 請求攔截器:增加 Loading
api.interceptors.request.use(config => {showLoading();return config;
});// 響應攔截器:移除 Loading
api.interceptors.response.use(response => {hideLoading();return response;},error => {hideLoading();return Promise.reject(error);}
);
📌 效果:
- 多個請求時,只顯示一個 Loading,所有請求完成后才關閉。
5. 自動重試請求(如 429 過載)
場景:
如果服務器返回 429 Too Many Requests
,可以實現自動重試,避免短時間內請求失敗。
api.interceptors.response.use(response => response,async error => {const { response, config } = error;if (response?.status === 429 && !config.__isRetryRequest) {config.__isRetryRequest = true;console.warn("請求過載,2 秒后重試...");await new Promise(resolve => setTimeout(resolve, 2000));return api(config); // 重新請求}return Promise.reject(error);}
);
📌 效果:
- 如果服務器返回
429
,攔截器會等待 2 秒后自動重試一次。
6. 數據格式轉換(響應攔截器)
場景:
后端返回的數據格式不符合前端要求,需要在攔截器中轉換。
api.interceptors.response.use(response => {if (response.data && response.data.result) {return response.data.result; // 提取需要的 `result` 數據}return response.data;
});
📌 效果:
- 假設后端返回
{ success: true, result: { name: "Tom" } }
,前端直接拿到{ name: "Tom" }
。
7. 記錄請求日志(請求攔截器 + 響應攔截器)
場景:
在開發模式下,打印請求和響應日志,方便調試。
api.interceptors.request.use(config => {console.log("🚀 請求:", config.method?.toUpperCase(), config.url, config.data);return config;
});api.interceptors.response.use(response => {console.log("? 響應:", response.config.url, response.data);return response;},error => {console.error("? 請求失敗:", error.config?.url, error.response?.status);return Promise.reject(error);}
);
📌 效果:
- 在開發者工具控制臺中,能看到請求和響應的日志信息,方便調試。
總結
攔截器類型 | 應用場景 | **示例代碼 |
---|---|---|
請求攔截器 | 統一添加 Token | config.headers.Authorization = Bearer ${token} |
請求攔截器 | 全局 Loading 處理 | showLoading() 和 hideLoading() |
響應攔截器 | 處理 401 未授權 | if (error.response.status === 401) { window.location.href = "/login"; } |
響應攔截器 | 統一錯誤提示 | message.error(error.response.data.message); |
響應攔截器 | 處理 429 過載自動重試 | await new Promise(resolve => setTimeout(resolve, 2000)); return api(config); |
響應攔截器 | 數據格式轉換 | return response.data.result; |
攔截器 | 請求 & 響應日志 | console.log("🚀 請求:", config) |
結論
Axios 攔截器非常強大,能幫助我們在全局范圍內 統一管理請求和響應,減少重復代碼,提升可維護性。實際項目中,可以根據需求選擇合適的攔截器組合,提升開發效率!