1. 安装 axios
首先,确保你已经安装了 axios
:
npm install axios
2. 设置 Axios 拦截器
import axios from 'axios';
// 创建一个 axios 实例
const axiosInstance = axios.create({
baseURL: 'http://localhost:8000/', // 后端 API 地址
timeout: 10000, // 设置超时时间
});
// 请求拦截器
axiosInstance.interceptors.request.use(
config => {
// 从 localStorage 获取 access_token
const token = localStorage.getItem('access_token');
if (token) {
// 如果存在 access_token,就将它添加到请求头
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
error => {
// 请求失败时的处理
return Promise.reject(error);
}
);
// 响应拦截器
axiosInstance.interceptors.response.use(
response => {
return response;
},
async error => {
const originalRequest = error.config;
// 如果响应的错误是 token 过期
if (error.response && error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
// 尝试用 refresh_token 刷新 access_token
const refreshToken = localStorage.getItem('refresh_token');
const response = await axios.post('http://localhost:8000/api/token/refresh/', {
refresh: refreshToken,
});
const { access } = response.data;
// 更新 access_token
localStorage.setItem('access_token', access);
// 设置新的 access_token 并重新发起原始请求
axiosInstance.defaults.headers['Authorization'] = `Bearer ${access}`;
originalRequest.headers['Authorization'] = `Bearer ${access}`;
return axiosInstance(originalRequest);
} catch (err) {
// 刷新 token 失败时的处理(例如 token 已过期或无效)
console.error('Token refresh failed:', err);
// 这里可以选择登出操作或其他处理
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
window.location.href = '/login'; // 重定向到登录页面
}
}
return Promise.reject(error);
}
);
export default axiosInstance;
3. 如何使用这个 Axios 实例
在你的项目中,使用 axiosInstance
来进行 API 请求,它会自动处理 Authorization
头以及 token 刷新逻辑。
import axiosInstance from './path/to/axiosInstance';
// 示例:登录请求
function login(username, password) {
axiosInstance.post('api/login/', { username, password })
.then(response => {
const { access, refresh } = response.data;
localStorage.setItem('access_token', access);
localStorage.setItem('refresh_token', refresh);
})
.catch(error => {
console.error('Login failed:', error);
});
}
// 示例:获取受保护资源
function getProtectedData() {
axiosInstance.get('api/protected-endpoint/')
.then(response => {
console.log('Protected data:', response.data);
})
.catch(error => {
console.error('Failed to fetch protected data:', error);
});
}
4. 解释代码
-
请求拦截器:每次请求发送前都会检查
localStorage
中是否有access_token
,如果有,它会将access_token
加入请求头Authorization
中。 -
响应拦截器:
- 如果返回的状态码是 401(即 token 过期或无效),拦截器会使用存储的
refresh_token
来刷新access_token
。 - 刷新成功后,它会将新的
access_token
存储到localStorage
中,并重新发起原始请求。 - 如果刷新失败(例如,
refresh_token
已失效),会移除所有 token,并重定向到登录页面。
- 如果返回的状态码是 401(即 token 过期或无效),拦截器会使用存储的
这样,每个 API 请求都会自动带上最新的 access_token
,并且在 token 过期时会自动刷新,保证用户的会话始终有效。