TypeScript中使用Axios的请求拦截器:概念、封装及错误处理
在现代Web开发中,与后端服务的交互是不可或缺的一部分。Axios是一个基于Promise的HTTP客户端,用于浏览器和node.js,它可以发送异步HTTP请求到你的后端服务。TypeScript作为JavaScript的一个超集,增加了类型系统和对ES6+新特性的支持,是构建大型应用的首选。本文将介绍如何在TypeScript项目中使用Axios的请求拦截器,包括基础封装、错误处理和认证配置。
1. 概念
Axios拦截器允许我们在请求或响应被then
或catch
处理之前对它们进行拦截。这在实际应用中非常有用,比如在发送请求前统一设置请求头,或者在返回响应后统一处理错误。
请求拦截器通常用于:
- 设置通用headers(如认证tokens)
- 检查或修改请求数据
- 设置请求的加载状态(如在UI中显示加载指示器)
响应拦截器通常用于:
- 处理接收到的数据(如格式化日期)
- 处理响应错误(如显示错误信息)
2. 基础封装
在TypeScript中,我们可以创建一个封装了Axios实例和拦截器的模块。这样不仅可以复用代码,还可以在项目中统一管理HTTP请求。
首先,安装Axios:
bash
npm install axios
然后创建一个axiosInstance.ts
文件:
typescript
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
:允许在将响应数据传递给then
或catch
之前对其进行修改。auth
:表示应该使用 HTTP 基本认证,并提供凭据。responseType
:表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'。responseEncoding
:表示对于responseType
为'text'的响应,如何解码响应,默认是 'utf8'。xsrfCookieName
/xsrfHeaderName
:用于防止XSRF攻击的cookie名称和header名称。
3. 错误处理
错误处理是请求拦截器中非常重要的一部分。当请求失败时,我们可以捕获错误并进行相应的处理,比如重定向到登录页面、显示错误提示等。
在响应拦截器的错误处理部分,我们可以根据HTTP状态码来决定如何处理错误:
typescript
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,并将其添加到请求头中:
typescript
config => {
const token = localStorage.getItem('token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
5. 完整示例
typescript
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实例和拦截器,我们可以在整个项目中保持代码的干净和一致性。记得处理各种网络异常和服务端错误,以提升用户体验。