1. 弁言
为什么需要请求和响应拦截?
在现代 Web 应用中,网络请求是不可或缺的一部分。为了进步开辟服从和代码质量,我们通常需要对请求和响应举行同一处理。例如:
- 请求头注入:在每次请求中主动添加认证信息。
- 错误同一处理:对网络错误或业务错误举行同一处理。
- 请求重试:在请求失败时主动重试。
- 请求取消:在组件卸载时取消未完成的请求。
Axios 提供了拦截器(Interceptors)功能,答应我们在请求发送之前和响应返回之后实验自界说逻辑。通过拦截器,我们可以轻松实现上述功能。
Axios 拦截器的应用场景
- 认证和授权:在请求头中主动添加 Token。
- 错误处理:对网络错误或业务错误举行同一处理。
- 数据格式化:对请求参数或响应数据举行格式化。
- 日记记录:记录请求和响应的具体信息。
2. Axios 简介
Axios 的核心特性
Axios 是一个基于 Promise 的 HTTP 客户端,具有以下核心特性:
- 支持浏览器和 Node.js:可以在浏览器和 Node.js 环境中使用。
- 拦截器:支持请求和响应拦截。
- 主动转换数据:主动将请求数据和响应数据转换为 JSON。
- 取消请求:支持取消未完成的请求。
Axios 的根本用法
以下是一个简单的 Axios 示例:
- import axios from 'axios';
- // 发送 GET 请求
- axios.get('/api/user')
- .then(response => console.log(response.data))
- .catch(error => console.error(error));
- // 发送 POST 请求
- axios.post('/api/user', { name: 'John' })
- .then(response => console.log(response.data))
- .catch(error => console.error(error));
复制代码 3. Axios 拦截器的工作原理
请求拦截器
请求拦截器答应我们在请求发送之前实验自界说逻辑。例如,可以在请求头中主动添加 Token。
- axios.interceptors.request.use(
- config => {
- // 在请求发送之前做一些处理
- return config;
- },
- error => {
- // 处理请求错误
- return Promise.reject(error);
- }
- );
复制代码 响应拦截器
响应拦截器答应我们在响应返回之后实验自界说逻辑。例如,可以对响应数据举行同一处理。
- axios.interceptors.response.use(
- response => {
- // 对响应数据进行处理
- return response;
- },
- error => {
- // 处理响应错误
- return Promise.reject(error);
- }
- );
复制代码 4. 实战:请求和响应拦截器的实现
项目初始化
使用 Vue CLI 或 Vite 创建一个新的 Vue 3 项目:
- npm create vite@latest my-vue-app --template vue-ts
- cd my-vue-app
- npm install
复制代码 安装 Axios:
实现请求拦截器
在 src/utils/request.ts 中创建 Axios 实例并实现请求拦截器。
- import axios, { AxiosRequestConfig } from 'axios';
- const instance = axios.create({
- baseURL: '/api',
- timeout: 10000,
- });
- // 请求拦截器
- instance.interceptors.request.use(
- (config: AxiosRequestConfig) => {
- // 在请求头中添加 Token
- const token = localStorage.getItem('token');
- if (token) {
- config.headers = config.headers || {};
- config.headers.Authorization = `Bearer ${token}`;
- }
- return config;
- },
- error => {
- return Promise.reject(error);
- }
- );
- export default instance;
复制代码 实现响应拦截器
在 src/utils/request.ts 中实现响应拦截器。
- instance.interceptors.response.use(
- response => {
- // 对响应数据进行处理
- return response.data;
- },
- error => {
- // 处理响应错误
- if (error.response) {
- switch (error.response.status) {
- case 401:
- // 未授权,跳转到登录页
- window.location.href = '/login';
- break;
- case 404:
- // 资源未找到
- console.error('Resource not found');
- break;
- default:
- console.error('An error occurred');
- }
- }
- return Promise.reject(error);
- }
- );
复制代码 联合 Vue 3 和 Pinia 举行状态管理
如果使用 Pinia 管理用户登录状态,可以在请求拦截器中从 Store 中获取 Token。
- import { useAuthStore } from '@/stores/auth';
- instance.interceptors.request.use(
- (config: AxiosRequestConfig) => {
- const authStore = useAuthStore();
- const token = authStore.token;
- if (token) {
- config.headers = config.headers || {};
- config.headers.Authorization = `Bearer ${token}`;
- }
- return config;
- },
- error => {
- return Promise.reject(error);
- }
- );
复制代码 5. 进阶:拦截器的常见应用场景
请求头注入
在请求拦截器中主动添加认证信息。
- instance.interceptors.request.use(
- config => {
- const token = localStorage.getItem('token');
- if (token) {
- config.headers = config.headers || {};
- config.headers.Authorization = `Bearer ${token}`;
- }
- return config;
- },
- error => {
- return Promise.reject(error);
- }
- );
复制代码 错误同一处理
在响应拦截器中对错误举行同一处理。
- instance.interceptors.response.use(
- response => {
- return response.data;
- },
- error => {
- if (error.response) {
- switch (error.response.status) {
- case 401:
- window.location.href = '/login';
- break;
- case 404:
- console.error('Resource not found');
- break;
- default:
- console.error('An error occurred');
- }
- }
- return Promise.reject(error);
- }
- );
复制代码 请求重试
在响应拦截器中实现请求重试逻辑。
- instance.interceptors.response.use(
- response => {
- return response.data;
- },
- async error => {
- const originalRequest = error.config;
- if (error.response.status === 401 && !originalRequest._retry) {
- originalRequest._retry = true;
- const newToken = await refreshToken(); // 刷新 Token
- localStorage.setItem('token', newToken);
- return instance(originalRequest); // 重试请求
- }
- return Promise.reject(error);
- }
- );
复制代码 请求取消
在组件卸载时取消未完成的请求。
- import { ref, onUnmounted } from 'vue';
- export default {
- setup() {
- const source = axios.CancelToken.source();
- const data = ref(null);
- axios.get('/api/data', { cancelToken: source.token })
- .then(response => data.value = response.data)
- .catch(error => {
- if (axios.isCancel(error)) {
- console.log('Request canceled', error.message);
- } else {
- console.error(error);
- }
- });
- onUnmounted(() => {
- source.cancel('Component unmounted');
- });
- return { data };
- },
- };
复制代码 6. 常见问题与办理方案
拦截器的实验顺序问题
如果注册了多个拦截器,它们的实验顺序是什么?
办理方案:拦截器按照注册顺序实验。请求拦截器先注册的先实验,响应拦截器后注册的先实验。
如那里理异步拦截器?
如果拦截器逻辑是异步的,如那里理?
办理方案:在拦截器中使用 async/await。
- instance.interceptors.request.use(
- async config => {
- const token = await getTokenAsync();
- if (token) {
- config.headers = config.headers || {};
- config.headers.Authorization = `Bearer ${token}`;
- }
- return config;
- },
- error => {
- return Promise.reject(error);
- }
- );
复制代码 拦截器的性能优化
如果拦截器逻辑复杂,大概会影响请求性能。
办理方案:将复杂的逻辑拆分为异步函数,或使用缓存机制。
7. 总结与预测
拦截器的最佳实践
- 明白拦截器逻辑:确保拦截器的逻辑清晰易懂。
- 避免重复处理:在拦截器中避免重复处理相同的逻辑。
- 联合状态管理:使用 Pinia 或 Vuex 管理用户登录状态。
将来发展方向
- 更细粒度的拦截器控制:支持更复杂的拦截器逻辑。
- 拦截器的插件化:将拦截器逻辑封装为插件,方便复用。
通过本文的学习,你应该已经把握了如安在项目中使用 Axios 的请求和响应拦截器。盼望这些内容能帮助你在现实项目中更好地处理网络请求!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |