当前位置:  首页>> 技术小册>> TypeScript和Vue从入门到精通(五)

14.2.3 拦截器的使用

在开发大型或复杂的前端应用时,特别是当涉及到与后端API的交互时,请求的发送与响应的处理往往成为关键的性能与优化点。Vue.js 结合 TypeScript 的项目中,通过引入HTTP客户端库(如Axios)并巧妙地使用拦截器(Interceptors),可以极大地提升代码的可维护性、复用性和错误处理能力。本章节将深入探讨在Vue.js与TypeScript环境下,如何使用Axios拦截器来优化网络请求与响应的处理流程。

14.2.3.1 拦截器概述

拦截器是Axios提供的一种强大的机制,允许你在请求被发送到服务器之前或响应从服务器返回之后,对它们进行拦截并处理。这种机制非常适合于全局性的错误处理、请求/响应数据的格式化、设置请求头、添加令牌认证等场景。

Axios的拦截器分为两类:

  • 请求拦截器(Request Interceptors):在请求发送之前执行。
  • 响应拦截器(Response Interceptors):在接收到响应之后执行。

14.2.3.2 设置请求拦截器

请求拦截器主要用于在请求发送之前对请求进行预处理,如添加统一的请求头、处理请求数据等。以下是一个在Vue.js与TypeScript环境中设置请求拦截器的示例:

  1. // src/plugins/axios.ts
  2. import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
  3. // 创建一个axios实例
  4. const service: AxiosInstance = axios.create({
  5. baseURL: process.env.VUE_APP_BASE_API, // api的base_url
  6. timeout: 5000 // 请求超时时间
  7. });
  8. // 请求拦截器
  9. service.interceptors.request.use(
  10. (config: AxiosRequestConfig) => {
  11. // 在发送请求之前做些什么
  12. // 例如,设置token
  13. if (store.getters.token) {
  14. config.headers['Authorization'] = `Bearer ${store.getters.token}`;
  15. }
  16. // 当你想对请求数据做点什么
  17. if (config.method === 'post') {
  18. // 假设config.data是请求体
  19. config.data = JSON.stringify(config.data);
  20. }
  21. return config;
  22. },
  23. (error) => {
  24. // 对请求错误做些什么
  25. console.error('请求拦截器捕获到错误:', error);
  26. return Promise.reject(error);
  27. }
  28. );
  29. export default service;

在这个例子中,我们创建了一个axios实例,并为其配置了基本的URL和超时时间。然后,我们为这个实例添加了一个请求拦截器,它在每个请求发送前都会被调用。在这个拦截器内部,我们检查了Vuex存储中的token(如果应用使用了Vuex进行状态管理),并将其添加到请求头中以实现身份验证。此外,我们还对POST请求的请求体进行了JSON字符串化处理。

14.2.3.3 设置响应拦截器

响应拦截器用于在接收到响应后进行一系列处理,如处理错误响应、统一响应数据格式等。以下是一个响应拦截器的示例:

  1. // 响应拦截器
  2. service.interceptors.response.use(
  3. (response: AxiosResponse) => {
  4. // 对响应数据做点什么
  5. // 例如,根据响应状态码进行错误处理
  6. const res = response.data;
  7. if (response.status !== 200) {
  8. console.error('接口响应错误:', response.status);
  9. // 这里可以抛出一个错误,由Vue的错误处理机制捕获
  10. return Promise.reject(new Error('接口响应错误'));
  11. } else {
  12. // 假设后端统一返回的数据结构为{code, data, message}
  13. if (res.code !== 200) {
  14. // 自定义业务错误处理
  15. return Promise.reject(new Error(res.message || 'Error'));
  16. } else {
  17. // 返回正常数据
  18. return res.data;
  19. }
  20. }
  21. },
  22. (error) => {
  23. // 对响应错误做点什么
  24. // 例如,网络错误的处理
  25. console.error('响应拦截器捕获到错误:', error);
  26. return Promise.reject(error);
  27. }
  28. );

在这个响应拦截器中,我们首先检查HTTP状态码,如果不是200,则直接打印错误信息并拒绝这个Promise,这样就可以通过Vue的错误处理机制(如全局错误处理器或组件内的catch语句)来捕获这个错误。然后,我们检查后端返回的业务状态码(这里假设后端统一了返回格式),如果业务状态码也不表示成功,则同样拒绝Promise并返回错误信息。只有当HTTP状态码和业务状态码都表示成功时,我们才返回实际的响应数据。

14.2.3.4 拦截器的移除

在某些情况下,你可能需要移除之前添加的拦截器,特别是在组件或页面销毁时,以避免内存泄漏或不必要的请求/响应处理。Axios提供了eject方法来移除拦截器,但需要注意的是,这个方法在Axios 0.21.0及之前的版本中并不存在,它是一个社区提出的建议但并未正式加入Axios。不过,你可以通过维护拦截器的引用并使用interceptors.request.ejectinterceptors.response.eject(如果这些方法被实现或模拟)来尝试移除拦截器。然而,更常见和推荐的做法是,在组件或页面销毁时不再发送新的请求,让现有的请求自然完成,并通过Vue的生命周期钩子或路由守卫来管理请求的取消或重试逻辑。

14.2.3.5 实战应用

在实际项目中,拦截器的使用远不止于上述示例。例如,你可以在请求拦截器中根据环境变量动态设置API的基准URL,或者在响应拦截器中实现自动重试机制(对于可重试的错误类型)。此外,你还可以利用拦截器来集成日志记录系统,将请求和响应数据发送到日志服务器进行监控和分析。

总之,拦截器是Axios提供的一个非常强大的功能,通过合理使用拦截器,你可以极大地提升Vue.js与TypeScript项目中网络请求的处理效率和可维护性。不过,也需要注意不要过度使用拦截器,特别是在请求/响应处理逻辑复杂时,应该考虑将逻辑拆分成更小的函数或服务,以保持代码的清晰和可测试性。


该分类下的相关小册推荐: