likes
comments
collection
share

TypeScript中使用Axios的请求拦截器:概念、封装及错误处理

作者站长头像
站长
· 阅读数 3

TypeScript中使用Axios的请求拦截器:概念、封装及错误处理

在现代Web开发中,与后端服务的交互是不可或缺的一部分。Axios是一个基于Promise的HTTP客户端,用于浏览器和node.js,它可以发送异步HTTP请求到你的后端服务。TypeScript作为JavaScript的一个超集,增加了类型系统和对ES6+新特性的支持,是构建大型应用的首选。本文将介绍如何在TypeScript项目中使用Axios的请求拦截器,包括基础封装、错误处理和认证配置。

1. 概念

Axios拦截器允许我们在请求或响应被thencatch处理之前对它们进行拦截。这在实际应用中非常有用,比如在发送请求前统一设置请求头,或者在返回响应后统一处理错误。

请求拦截器通常用于:

  • 设置通用headers(如认证tokens)
  • 检查或修改请求数据
  • 设置请求的加载状态(如在UI中显示加载指示器)

响应拦截器通常用于:

  • 处理接收到的数据(如格式化日期)
  • 处理响应错误(如显示错误信息)

2. 基础封装

在TypeScript中,我们可以创建一个封装了Axios实例和拦截器的模块。这样不仅可以复用代码,还可以在项目中统一管理HTTP请求。

首先,安装Axios:

npm install axios

然后创建一个axiosInstance.ts文件:

import axios from 'axios';

// 创建axios实例
const axiosInstance = axios.create({
  baseURL: 'https://api.yourservice.com', // API服务的基础URL
  timeout: 10000, // 请求超时时间
});

// 请求拦截器
axiosInstance.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么,例如插入token
    const token = localStorage.getItem('token');
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

// 响应拦截器
axiosInstance.interceptors.response.use(
  response => {
    // 对响应数据做点什么
    return response.data;
  },
  error => {
    // 对响应错误做点什么
    return Promise.reject(error);
  }
);

export default axiosInstance;

除了上面的baseURL和超时时间之外其实还有一些其他的配置项

  • baseURL:基础请求URL,所有的请求都会基于这个URL进行。
  • timeout:指定请求超时的毫秒数,如果请求时间超过timeout,请求将被中断。
  • headers:要发送的自定义headers。
  • params:URL参数,将自动附加到URL上。
  • paramsSerializer:一个负责params序列化的函数。
  • transformRequest:允许在将请求数据发送到服务器之前对其进行修改。
  • transformResponse:允许在将响应数据传递给thencatch之前对其进行修改。
  • auth:表示应该使用 HTTP 基本认证,并提供凭据。
  • responseType:表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'。
  • responseEncoding:表示对于responseType为'text'的响应,如何解码响应,默认是 'utf8'。
  • xsrfCookieName / xsrfHeaderName:用于防止XSRF攻击的cookie名称和header名称。

3. 错误处理

错误处理是请求拦截器中非常重要的一部分。当请求失败时,我们可以捕获错误并进行相应的处理,比如重定向到登录页面、显示错误提示等。

在响应拦截器的错误处理部分,我们可以根据HTTP状态码来决定如何处理错误:

axiosInstance.interceptors.response.use(
  response => {
    // 请求成功的处理
    return response.data;
  },
  error => {
    // 请求失败的处理
    if (error.response) {
      switch (error.response.status) {
        case 401:
          // token过期或未授权
          // 可以进行重定向到登录页面,或者弹出提示等操作
          break;
        // 其他状态码相应处理
        default:
          // 处理其他状态码
      }
    } else if (error.request) {
      // 请求已发出,但没有收到响应
      // 'error.request' 在浏览器中是 XMLHttpRequest 的实例,在node.js中是 http.ClientRequest 的实例
    } else {
      // 发送请求时出了点问题
    }
    return Promise.reject(error);
  }
);

4. 认证配置

在请求拦截器中,我们通常需要添加认证信息,比如JWT token。这些信息通常存储在localStorage或cookie中,拦截器会在每次请求发送前将其添加到请求头中。

如上面代码所示,我们在请求拦截器中检查localStorage是否有token,并将其添加到请求头中:

config => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers['Authorization'] = `Bearer ${token}`;
  }
  return config;
},

5. 完整示例

import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';

// 创建axios实例
const axiosInstance = axios.create({
  baseURL: 'https://api.yourservice.com', // 替换为你的API服务的基础URL
  timeout: 10000, // 请求超时时间
  // headers: {
  //   'Content-Type': 'application/json', // 默认内容类型
  //   'Custom-Header': 'Custom Value' // 自定义头信息
  // },
  // responseType: 'json', // 默认响应类型
  // responseEncoding: 'utf8', // 默认编码
});

// 请求拦截器
axiosInstance.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: AxiosError) => {
    // 对请求错误做些什么
    console.error('Request error:', error);
    return Promise.reject(error);
  }
);

// 响应拦截器
axiosInstance.interceptors.response.use(
  (response: AxiosResponse) => {
    // 对响应数据做点什么
    return response.data;
  },
  (error: AxiosError) => {
    // 对响应错误做点什么
    if (error.response) {
      // 根据返回的HTTP状态码做不同的处理
      switch (error.response.status) {
        case 401:
          // token过期或未授权
          console.error('Unauthorized! Token may have expired.');
          // 这里可以添加跳转到登录页面的逻辑
          break;
        case 403:
          console.error('Forbidden! You do not have permission to perform this action.');
          // 这里可以添加一些权限不足的处理逻辑
          break;
        case 404:
          console.error('Not Found! The requested resource was not found.');
          // 这里可以添加一些资源未找到的处理逻辑
          break;
        // 其他状态码相应处理
        default:
          console.error(`[Error]: ${error.response.status} - ${error.response.statusText}`);
      }
    } else if (error.request) {
      // 请求已发出,但没有收到响应
      console.error('No response received:', error.request);
    } else {
      // 发送请求时出了点问题
      console.error('Error setting up request:', error.message);
    }
    // 可以在这里对所有的响应错误统一处理
    return Promise.reject(error);
  }
);
export default axiosInstance;

Axios的请求拦截器在TypeScript项目中非常有用,它可以帮助我们统一处理请求和响应,管理认证信息,以及优化错误处理。通过封装Axios实例和拦截器,我们可以在整个项目中保持代码的干净和一致性。记得处理各种网络异常和服务端错误,以提升用户体验。