Axios 请求和响应拦截项目实践

打印 上一主题 下一主题

主题 931|帖子 931|积分 2803



  
1. 弁言

为什么需要请求和响应拦截?

在现代 Web 应用中,网络请求是不可或缺的一部分。为了进步开辟服从和代码质量,我们通常需要对请求和响应举行同一处理。例如:


  • 请求头注入:在每次请求中主动添加认证信息。
  • 错误同一处理:对网络错误或业务错误举行同一处理。
  • 请求重试:在请求失败时主动重试。
  • 请求取消:在组件卸载时取消未完成的请求。
Axios 提供了拦截器(Interceptors)功能,答应我们在请求发送之前和响应返回之后实验自界说逻辑。通过拦截器,我们可以轻松实现上述功能。
Axios 拦截器的应用场景



  • 认证和授权:在请求头中主动添加 Token。
  • 错误处理:对网络错误或业务错误举行同一处理。
  • 数据格式化:对请求参数或响应数据举行格式化。
  • 日记记录:记录请求和响应的具体信息。

2. Axios 简介

Axios 的核心特性

Axios 是一个基于 Promise 的 HTTP 客户端,具有以下核心特性:


  • 支持浏览器和 Node.js:可以在浏览器和 Node.js 环境中使用。
  • 拦截器:支持请求和响应拦截。
  • 主动转换数据:主动将请求数据和响应数据转换为 JSON。
  • 取消请求:支持取消未完成的请求。
Axios 的根本用法

以下是一个简单的 Axios 示例:
  1. import axios from 'axios';
  2. // 发送 GET 请求
  3. axios.get('/api/user')
  4.   .then(response => console.log(response.data))
  5.   .catch(error => console.error(error));
  6. // 发送 POST 请求
  7. axios.post('/api/user', { name: 'John' })
  8.   .then(response => console.log(response.data))
  9.   .catch(error => console.error(error));
复制代码

3. Axios 拦截器的工作原理

请求拦截器

请求拦截器答应我们在请求发送之前实验自界说逻辑。例如,可以在请求头中主动添加 Token。
  1. axios.interceptors.request.use(
  2.   config => {
  3.     // 在请求发送之前做一些处理
  4.     return config;
  5.   },
  6.   error => {
  7.     // 处理请求错误
  8.     return Promise.reject(error);
  9.   }
  10. );
复制代码
响应拦截器

响应拦截器答应我们在响应返回之后实验自界说逻辑。例如,可以对响应数据举行同一处理。
  1. axios.interceptors.response.use(
  2.   response => {
  3.     // 对响应数据进行处理
  4.     return response;
  5.   },
  6.   error => {
  7.     // 处理响应错误
  8.     return Promise.reject(error);
  9.   }
  10. );
复制代码

4. 实战:请求和响应拦截器的实现

项目初始化

使用 Vue CLI 或 Vite 创建一个新的 Vue 3 项目:
  1. npm create vite@latest my-vue-app --template vue-ts
  2. cd my-vue-app
  3. npm install
复制代码
安装 Axios:
  1. npm install axios
复制代码
实现请求拦截器

在 src/utils/request.ts 中创建 Axios 实例并实现请求拦截器。
  1. import axios, { AxiosRequestConfig } from 'axios';
  2. const instance = axios.create({
  3.   baseURL: '/api',
  4.   timeout: 10000,
  5. });
  6. // 请求拦截器
  7. instance.interceptors.request.use(
  8.   (config: AxiosRequestConfig) => {
  9.     // 在请求头中添加 Token
  10.     const token = localStorage.getItem('token');
  11.     if (token) {
  12.       config.headers = config.headers || {};
  13.       config.headers.Authorization = `Bearer ${token}`;
  14.     }
  15.     return config;
  16.   },
  17.   error => {
  18.     return Promise.reject(error);
  19.   }
  20. );
  21. export default instance;
复制代码
实现响应拦截器

在 src/utils/request.ts 中实现响应拦截器。
  1. instance.interceptors.response.use(
  2.   response => {
  3.     // 对响应数据进行处理
  4.     return response.data;
  5.   },
  6.   error => {
  7.     // 处理响应错误
  8.     if (error.response) {
  9.       switch (error.response.status) {
  10.         case 401:
  11.           // 未授权,跳转到登录页
  12.           window.location.href = '/login';
  13.           break;
  14.         case 404:
  15.           // 资源未找到
  16.           console.error('Resource not found');
  17.           break;
  18.         default:
  19.           console.error('An error occurred');
  20.       }
  21.     }
  22.     return Promise.reject(error);
  23.   }
  24. );
复制代码
联合 Vue 3 和 Pinia 举行状态管理

如果使用 Pinia 管理用户登录状态,可以在请求拦截器中从 Store 中获取 Token。
  1. import { useAuthStore } from '@/stores/auth';
  2. instance.interceptors.request.use(
  3.   (config: AxiosRequestConfig) => {
  4.     const authStore = useAuthStore();
  5.     const token = authStore.token;
  6.     if (token) {
  7.       config.headers = config.headers || {};
  8.       config.headers.Authorization = `Bearer ${token}`;
  9.     }
  10.     return config;
  11.   },
  12.   error => {
  13.     return Promise.reject(error);
  14.   }
  15. );
复制代码

5. 进阶:拦截器的常见应用场景

请求头注入

在请求拦截器中主动添加认证信息。
  1. instance.interceptors.request.use(
  2.   config => {
  3.     const token = localStorage.getItem('token');
  4.     if (token) {
  5.       config.headers = config.headers || {};
  6.       config.headers.Authorization = `Bearer ${token}`;
  7.     }
  8.     return config;
  9.   },
  10.   error => {
  11.     return Promise.reject(error);
  12.   }
  13. );
复制代码
错误同一处理

在响应拦截器中对错误举行同一处理。
  1. instance.interceptors.response.use(
  2.   response => {
  3.     return response.data;
  4.   },
  5.   error => {
  6.     if (error.response) {
  7.       switch (error.response.status) {
  8.         case 401:
  9.           window.location.href = '/login';
  10.           break;
  11.         case 404:
  12.           console.error('Resource not found');
  13.           break;
  14.         default:
  15.           console.error('An error occurred');
  16.       }
  17.     }
  18.     return Promise.reject(error);
  19.   }
  20. );
复制代码
请求重试

在响应拦截器中实现请求重试逻辑。
  1. instance.interceptors.response.use(
  2.   response => {
  3.     return response.data;
  4.   },
  5.   async error => {
  6.     const originalRequest = error.config;
  7.     if (error.response.status === 401 && !originalRequest._retry) {
  8.       originalRequest._retry = true;
  9.       const newToken = await refreshToken(); // 刷新 Token
  10.       localStorage.setItem('token', newToken);
  11.       return instance(originalRequest); // 重试请求
  12.     }
  13.     return Promise.reject(error);
  14.   }
  15. );
复制代码
请求取消

在组件卸载时取消未完成的请求。
  1. import { ref, onUnmounted } from 'vue';
  2. export default {
  3.   setup() {
  4.     const source = axios.CancelToken.source();
  5.     const data = ref(null);
  6.     axios.get('/api/data', { cancelToken: source.token })
  7.       .then(response => data.value = response.data)
  8.       .catch(error => {
  9.         if (axios.isCancel(error)) {
  10.           console.log('Request canceled', error.message);
  11.         } else {
  12.           console.error(error);
  13.         }
  14.       });
  15.     onUnmounted(() => {
  16.       source.cancel('Component unmounted');
  17.     });
  18.     return { data };
  19.   },
  20. };
复制代码

6. 常见问题与办理方案

拦截器的实验顺序问题

如果注册了多个拦截器,它们的实验顺序是什么?
办理方案:拦截器按照注册顺序实验。请求拦截器先注册的先实验,响应拦截器后注册的先实验。
如那里理异步拦截器?

如果拦截器逻辑是异步的,如那里理?
办理方案:在拦截器中使用 async/await。
  1. instance.interceptors.request.use(
  2.   async config => {
  3.     const token = await getTokenAsync();
  4.     if (token) {
  5.       config.headers = config.headers || {};
  6.       config.headers.Authorization = `Bearer ${token}`;
  7.     }
  8.     return config;
  9.   },
  10.   error => {
  11.     return Promise.reject(error);
  12.   }
  13. );
复制代码
拦截器的性能优化

如果拦截器逻辑复杂,大概会影响请求性能。
办理方案:将复杂的逻辑拆分为异步函数,或使用缓存机制。

7. 总结与预测

拦截器的最佳实践



  • 明白拦截器逻辑:确保拦截器的逻辑清晰易懂。
  • 避免重复处理:在拦截器中避免重复处理相同的逻辑。
  • 联合状态管理:使用 Pinia 或 Vuex 管理用户登录状态。
将来发展方向



  • 更细粒度的拦截器控制:支持更复杂的拦截器逻辑。
  • 拦截器的插件化:将拦截器逻辑封装为插件,方便复用。

通过本文的学习,你应该已经把握了如安在项目中使用 Axios 的请求和响应拦截器。盼望这些内容能帮助你在现实项目中更好地处理网络请求!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

来自云龙湖轮廓分明的月亮

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表