Slogan:易用、简洁且高效的http库。
官网:http://www.axios-js.com/zh-cn/
文档:http://www.axios-js.com/zh-cn/docs/
https://blog.csdn.net/qq_29689343/article/details/109193487
https://blog.csdn.net/qq_29689343/article/details/109193620
https://blog.csdn.net/qq_29689343/article/details/118193238
使用示例,仅作为参考!
pnpm add axios
token
状态/src/store/token.ts
// import api from '@/api'
import { defineStore } from 'pinia';
const useTokenStore = defineStore(
// 唯一ID
'token',
{
state: () => ({
token: localStorage.token,
failuretime: localStorage.failuretime,
}),
getters: {
isLogin: (state) => {
let retn = false;
if (state.token != null) {
const unix = Date.parse(new Date().toString());
if (unix < state.failuretime * 1000) {
retn = true;
}
}
return retn;
},
},
actions: {
login() {
return new Promise<void>((resolve) => {
// 模拟登录成功,写入 token 信息
localStorage.setItem('token', '1234567890');
localStorage.setItem(
'failuretime',
(
Date.parse(new Date().toString()) / 1000 +
24 * 60 * 60
).toString(),
);
this.token = '1234567890';
this.failuretime =
Date.parse(new Date().toString()) / 1000 + 24 * 60 * 60;
resolve();
});
},
// login(data) {
// return new Promise((resolve, reject) => {
// api.post('member/login', data).then((res) => {
// localStorage.setItem('token', '1234567890')
// localStorage.setItem('failuretime', Date.parse(new Date()) / 1000 + 24 * 60 * 60)
// this.token = '1234567890'
// this.failuretime = Date.parse(new Date()) / 1000 + 24 * 60 * 60
// resolve(res)
// }).catch((error) => {
// reject(error)
// })
// })
// },
logout() {
return new Promise<void>((resolve) => {
// 模拟退出登录,清除 token 信息
localStorage.removeItem('token');
localStorage.removeItem('failuretime');
this.token = null;
this.failuretime = null;
resolve();
});
},
},
},
);
export default useTokenStore;
axios
封装/src/api/index.ts
import axios from 'axios';
// import qs from 'qs'
import router from '@/router/index';
import useTokenStore from '@/store/token';
// 登录
async function toLogin() {
await useTokenStore().logout();
await router.push({
path: '/login',
query: {
redirect: router.currentRoute.value.fullPath,
},
});
}
// axios 实例
const api = axios.create({
baseURL:
import.meta.env.DEV && import.meta.env.VITE_OPEN_PROXY === 'true'
? '/proxy/'
: import.meta.env.VITE_APP_API_BASEURL,
timeout: 1000 * 60,
responseType: 'json',
});
/**
* 请求拦截器
*/
api.interceptors.request.use((config) => {
const tokenStore = useTokenStore();
/**
* 全局拦截请求发送前提交的参数
* 以下代码为示例,在请求头里带上 token 信息
*/
if (tokenStore.isLogin && config.headers) {
config.headers.Token = tokenStore.token;
}
// 是否将 POST 请求参数进行字符串化处理
if (config.method === 'post') {
// config.data = qs.stringify(config.data, {
// arrayFormat: 'brackets',
// })
}
return config;
});
/**
* 响应拦截器
*/
api.interceptors.response.use(
async (response) => {
/**
* 全局拦截请求发送后返回的数据,如果数据有报错则在这做全局的错误提示
* 假设返回数据格式为:{ status: 1, error: '', data: '' }
* 规则是当 status 为 1 时表示请求成功,为 0 时表示接口需要登录或者登录状态失效,需要重新登录
* 请求出错时 error 会返回错误信息
*/
if (response.data.status === 1) {
if (response.data.error !== '') {
// 这里做错误提示,如果使用了 element plus 则可以使用 Message 进行提示
// Message.error(options)
return Promise.reject(response.data);
}
} else {
await toLogin();
}
return Promise.resolve(response.data);
},
(error) => {
let message = error.message;
if (message === 'Network Error') {
message = '后端网络故障';
} else if (message.includes('timeout')) {
message = '接口请求超时';
} else if (message.includes('Request failed with status code')) {
message = `接口${message.substr(message.length - 3)}异常`;
}
return Promise.reject(error);
},
);
export default api;
在根目录 .env.*
文件里的 VITE_APP_API_BASEURL
这个参数就是配置 axios 的 baseURL
。
例如项目的真实接口请求地址为:
http://api.test.com/news/list
http://api.test.com/news/create
http://api.test.com/shop/info
则可设置为 VITE_APP_API_BASEURL = http://api.test.com/
。
常用的 get 和 post 请求可使用以下的方法:
any 应该被替换成具体的类型!
import api from '@/api';
// GET 请求
export const getList = () => {
return api.get<any>('/list', {
params: {
page: 1,
size: 10,
},
});
};
// POST 请求
export const createNews = () => {
return api.post<any>('news/create', {
title: '新闻标题',
content: '新闻内容',
});
};
在 /src/api/index.ts
文件里实例化了 axios
对象,并对 request 和 response 设置了拦截器,拦截器的用处就是拦截每一次的请求和响应,然后做一些全局的处理。例如接口响应报错,可以在拦截器里用统一的报错提示来展示,方便业务开发。但因为每个公司提供的接口标准不同,所以该文件拦截器部分的代码,需要开发者根据实际情况去修改调整。
代码很简单,首先初始化 axios 对象,然后 axios.interceptors.request.use()
和 axios.interceptors.response.use()
就分别是请求和响应的拦截代码了。
参考代码里只做了简单的拦截处理,例如请求的时候会自动带上 token ,响应的时候会根据错误信息判断是登录失效还是接口报错,并做相应动作。
更复杂(完整)的封装,可参考 vben 的封装。
https://blog.csdn.net/qq_29689343/article/details/118193238