什么是axios
axios是一款基于Promise的HTTP客户端,适用于浏览器和Node.js环境。它的特点包括:
- 支持浏览器和Node.js环境。
- 支持Promise API。
- 支持拦截请求和响应。
- 支持取消请求。
- 自动转换JSON数据。
- 支持CSRF保护。
使用axios可以更方便地发送HTTP请求,并且对请求和响应进行拦截、转换等处理。它可以在浏览器端和Node.js环境中使用,很适用于进行数据交互。
安装axios
yarn add axios
创建token工具方法
// 定义访问令牌的常量键名
export const ACCESS_TOKEN = 'access_token';
// 获取访问令牌
export const getAccessToken = () => {
return localStorage.getItem(ACCESS_TOKEN);
};
// 设置访问令牌
export const setAccessToken = (token: string) => {
localStorage.setItem(ACCESS_TOKEN, token);
};
// 移除访问令牌
export const removeAccessToken = () => {
localStorage.removeItem(ACCESS_TOKEN);
};
// 用于模拟刷新令牌的函数,可根据实际需求替换为真实刷新逻辑
export const refreshAccessToken = async () => {
return Promise.resolve('123456'); // 返回新的令牌
};
request
工具方法
当然,以下是一个更具体的分步骤介绍代码块的 Markdown 博文示例:
创建 Axios 实例
首先,我们需要创建一个 Axios 实例并配置默认请求头。这个实例将用于所有的网络请求。以下是创建 Axios 实例的示例代码:
import axios, { AxiosInstance, AxiosResponse, AxiosError } from 'axios';
import { API_HOST, LOGIN_URL } from './config';
// 创建一个 Axios 实例并配置默认请求头
const instance: AxiosInstance = axios.create({
baseURL: API_HOST, // 设置基本 URL
});
请求拦截器
请求拦截器用于修改请求配置,例如添加身份验证标头。以下是请求拦截器的示例代码:
instance.interceptors.request.use(
(config) => {
let { url } = config;
if (!url) {
throw new Error('url不能为空');
}
if (url.indexOf('://') === -1) {
url = `${API_HOST}${url}`;
}
const modifiedConfig = { ...config, url };
if (!(modifiedConfig.data instanceof FormData)) {
modifiedConfig.headers['Content-Type'] = 'application/json';
}
// 如果有访问令牌,将其添加到请求头
const token = getAccessToken();
if (token) {
modifiedConfig.headers.Authorization = `JWT ${token}`;
}
return config;
},
async (error) => Promise.reject(error),
);
响应拦截器
响应拦截器用于处理响应,包括处理错误和刷新令牌。以下是响应拦截器的示例代码:
// 响应拦截器:用于处理响应
instance.interceptors.response.use(
(response: AxiosResponse) => {
if (response.status === 204) {
return response;
}
return response.data;
},
async (error: AxiosError) => {
const { response } = error;
if (response?.status === 401) {
try {
// 尝试无感刷新token
const newAccessToken = await refreshAccessToken();
setAccessToken(newAccessToken);
const originalRequest = error.config;
if (originalRequest) {
originalRequest.headers.Authorization = `JWT ${newAccessToken}`;
// 重新发送原始请求
return axios(originalRequest);
}
} catch (refreshError) {
removeAccessToken();
// 处理未授权 (401) 响应,重定向到登录页面
const redirectUri = window.location.href;
let secondsToLogin: number = 5;
const modal = Modal.error({
title: '凭证失效',
content: `你的登录凭证已失效,${secondsToLogin}s后将跳转到登录页面`,
});
const timer = setInterval(() => {
secondsToLogin -= 1;
modal.update({
content: `你的登录凭证已失效,${secondsToLogin}s后将跳转到登录页面`,
okText: '立即登录',
afterClose: () => {
clearInterval(timer);
window.location.href = `${LOGIN_URL}?${stringify({
redirectUri,
})}`;
},
});
});
setTimeout(() => {
clearInterval(timer);
modal.destroy();
}, secondsToLogin * 1000);
}
}
// 处理网络错误,显示通知
notification.error({
message: '网络错误,请联系管理员',
});
return Promise.reject(error);
},
);