53、axios请求拦截器/响应拦截器

一般在使用axios时,会用到拦截器的功能,一般分为两种:请求拦截器、响应拦截器。
1.请求拦截器

在请求发送前进行必要操作处理,例如添加统一cookie、请求体加验证、设置请求头等,相当于是对每个接口里相同操作的一个封装;

首先,它可以用于统一处理请求。例如,在发送多个网络请求时,可能需要在每个请求头中添加相同的认证信息(像 token)来验证用户身份。通过请求拦截器,就可以把添加认证信息这个操作集中处理,不用在每个请求代码里单独添加,这样能提高代码的可维护性。

其次,能够进行请求预处理。比如对请求参数进行统一的格式化或者加密处理。假设应用需要对发送的用户数据进行加密,请求拦截器就可以在请求发送前自动完成加密步骤。

再者,有助于进行错误处理和日志记录。可以在拦截器中捕获网络请求开始前的错误,比如网络连接异常或者请求参数不符合要求等情况。同时,也能够记录请求的详细信息,像请求的 URL、参数等内容,方便后续排查问题。

2.响应拦截器

同理,响应拦截器也是如此功能,只是在请求得到响应之后,对响应体的一些处理,通常是数据统一处理等,也常来判断登录失效等

import axios from "axios";
import router from "路由文件地址"; // 获取路由

const request = axios.create({
	baseURL:"xxx",  
	timeout:20000, 
})

// 请求拦截器
request.interceptors.request.use(
	(config)=>{
		if(config.url !== "/sys/login"){   // 判断请求是否是登录接口
			config.headers.token = sessionStorage.getItem("token"); // 如果不是登录接口,就给请求头里面设置token
		}
		return config; // 返回这个配置对象,如果没有返回,这个请求就不会发送出去
	},
	(error)=>{
		return Promise.reject(error);
	}
)

// 响应拦截器
request.interceptors.response.use(
	(res)=>{
		let code = res.data.code  // 获取后端返回的状态码
		if(code===200){           // 成功
			return res.data.data  // 返回里面的数据,在使用这个axios时,获取到的东西就是这里返回的东西
		}else if (code == 401) {  // token失效
      		router.push("/login");  // 跳转登录页
    	}else{
			return res.data   
		}
	},
	(error)=>{
		return Promise.reject(error);
	}
)

export default request;

### 使用 Axios 请求拦截器实现 Token 刷新机制 在实际开发过程中,Token 可能会过期,因此需要设计一种机制来刷新 Token 并重新发起请求。以下是通过 Axios 请求拦截器实现 Token 刷新的具体方法。 #### 1. 配置 Axios 基础选项 首先配置 Axios 的基础选项,例如根路径和默认头部信息: ```javascript import axios from 'axios'; // 设置全局的基础 URL 和超时时间 axios.defaults.baseURL = 'https://api.example.com'; // 替换为你的 API 地址 axios.defaults.timeout = 5000; // 定义一个标志位用于防止多次触发刷新逻辑 let isRefreshing = false; let failedQueue = []; ``` 上述代码设置了 Axios 的基础 URL 和超时时间[^3],并初始化了一个 `isRefreshing` 标志变量以及失败队列 `failedQueue` 来管理因 Token 过期而被中断的请求。 --- #### 2. 创建请求拦截器请求拦截器中添加 Authorization 头部,并处理可能存在的 Token 缺失情况: ```javascript axios.interceptors.request.use( (config) => { const token = localStorage.getItem('token'); // 获取存储中的 Token if (token && !config.headers.Authorization) { config.headers.Authorization = `Bearer ${token}`; // 添加到请求头中 } return config; }, (error) => Promise.reject(error) ); ``` 此部分实现了基本的 Token 自动附加功能[^2]。 --- #### 3. 创建响应拦截器以捕获 Token 过期错误 当服务器返回特定状态码(如 401 Unauthorized)表示 Token 已失效时,可以尝试刷新 Token 或重定向至登录页: ```javascript axios.interceptors.response.use( (response) => response, async (error) => { const originalRequest = error.config; if (error.response.status === 401 && !originalRequest._retry) { if (isRefreshing) { // 如果已经在刷新,则加入等待队列 return new Promise((resolve, reject) => { failedQueue.push(() => { resolve(axios(originalRequest)); }); }); } originalRequest._retry = true; isRefreshing = true; try { // 调用刷新 Token 接口 const refreshTokenResponse = await axios.post('/auth/refresh-token', { refresh_token: localStorage.getItem('refresh_token'), }); if (refreshTokenResponse.data.token) { localStorage.setItem('token', refreshTokenResponse.data.token); // 更新本地存储中的 Token axios.defaults.headers.common['Authorization'] = `Bearer ${refreshTokenResponse.data.token}`; // 执行失败队列中的请求 failedQueue.forEach(callback => callback()); failedQueue = []; return axios(originalRequest); // 重新发送原始请求 } else { throw new Error('Failed to fetch a new access token.'); } } catch (err) { console.error('Refresh token request failed:', err.message); // 清除旧 Token 并跳转到登录页面 localStorage.removeItem('token'); localStorage.removeItem('refresh_token'); window.location.href = '/login'; } finally { isRefreshing = false; } } return Promise.reject(error); } ); ``` 该段代码的核心在于检测到 401 错误后执行 Token 刷新操作[^1]。如果刷新成功,则更新当前请求和其他挂起的请求;如果刷新失败,则清除所有 Token 并引导用户重新登录。 --- #### 4. 测试与注意事项 - **测试场景**:模拟 Token 过期的情况,观察是否能够正常刷新或提示用户重新登录。 - **安全性注意**:确保 Refresh Token 存储安全,避免泄露风险。 - **性能优化**:减少不必要的重复刷新动作,利用 `isRefreshing` 控制并发行为。 --- ### 总结 以上展示了如何基于 Axios 请求拦截器构建一套完整的 Token 刷新机制。它不仅可以提升用户体验,还能有效降低手动维护 Token 的复杂度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值