vue项目封装axios请求,支持判断当前环境及判断token是否过期等等(详细教程,可复制粘贴代码)
目录
1.准备工作,创建js/ts文件,用于写封装axios的代码
2.准备工作,创建常见网络请求状态码信息文件
1.在项目根目录的utils文件夹中创建status.ts文件
2.复制粘贴以下代码,有需要可以自行删改,以下是本人常用的
3.准备工作,创建不同环境所使用的访问地址存放的文件
1.在项目根目录创建.env文件
2.配置对应环境的访问地址
4.封装axios请求
1.在第1步中创建的request.ts文件中粘贴以下代码
2.使用token配置请求头解释
3.token(登录)过期解释
4.自动判断运行环境,并采用不同的访问接口解释
5.在其他文件引入和使用封装好的axios请求
1.文件夹结构例子,在login.ts中引入和使用
2.引入和使用
3.在.vue文件中引入登录请求方法和使用
一个应用中,网络请求是必不可少的,vue项目中,常常使用Axios 请求。Axios 是一个基于 Promise 的 HTTP 客户端,用于在浏览器和 node.js 中发送 HTTP 请求。下面给大家介绍一下如何封装Axios ,以及封装时常常会增加的一些功能。
1.准备工作,创建js/ts文件,用于写封装axios的代码
注意:根据项目的实际情况使用js/ts文件,以下.ts文件亦可为.js文件,不再重复讲述了
vue项目中,通常在项目根目录的utils文件夹中创建封装axios的文件(如果没有就新建一个),以此为例子,创建request.ts文件
2.准备工作,创建常见网络请求状态码信息文件
用于发起网络请求遇到常见问题时的提示
1.在项目根目录的utils文件夹中创建status.ts文件
2.复制粘贴以下代码,有需要可以自行删改,以下是本人常用的
export const showMessage = (status: number | string): string => {let message: string = "";switch (status) {case 400:message = "请求错误(400)";break;case 401:message = "未授权,请重新登录(401)";break;case 403:message = "拒绝访问(403)";break;case 404:message = "请求出错(404)";break;case 408:message = "请求超时(408)";break;case 500:message = "服务器错误(500)";break;case 501:message = "服务未实现(501)";break;case 502:message = "网络错误(502)";break;case 503:message = "服务不可用(503)";break;case 504:message = "网络超时(504)";break;case 505:message = "HTTP版本不受支持(505)";break;default:message = `连接出错(${status})!`;}return `${message},请检查网络或联系管理员!`;
};
3.准备工作,创建不同环境所使用的访问地址存放的文件
通常不同的环境使用不同的访问地址,以生产环境和开发环境为例
1.在项目根目录创建.env文件
第一个文件是开发环境,第二个文件是生产环境
2.配置对应环境的访问地址
# .env.development
# 开发环境
VITE_APP_ENV = 'development'
VUE_APP_API_URL = '/api' // 接口地址的前缀,例如有接口:/api/login/numLogin,就可以把/api写在这里,根据后端实际地址VITE_APP_BASE_URL = '' // 单引号内写你的开发环境地址
# .env.production
# 生产环境
VITE_APP_ENV = 'production'
VUE_APP_API_URL = ''# 服务器地址
# VITE_APP_BASE_URL = '' // 单引号内写你的生产环境地址
4.封装axios请求
1.在第1步中创建的request.ts文件中粘贴以下代码
注意:接口超时时间、token过期判断、token过期处理等都更具你的实际情况删改,以下为本人常用的代码
import axios from "axios";
import { showMessage } from "./status"; // 引入状态码(第2步创建的文件)
import { ElMessage } from "element-plus"; // 引入提示框(以使用elementPlus这个UI库为例)
import { useRouter } from 'vue-router';
const router = useRouter(); // 获取路由实例
// 设置接口超时时间
axios.defaults.timeout = 60000;
axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';// console.log('当前环境', import.meta.env.VITE_APP_ENV);
// console.log('地址', import.meta.env.VITE_APP_BASE_URL);// 判断当前的运行环境,可作出对应处理
if (import.meta.env.VITE_APP_ENV === "production") {// 生产环境axios.defaults.baseURL = import.meta.env.VITE_APP_BASE_URL;// 可根据需要写接口,也可以用第3步.env文件配置的接口
} else if (import.meta.env.VITE_APP_ENV === "development") {// 开发环境axios.defaults.baseURL = '/api' // 可根据需要写接口,也可以用第3步.env文件配置的接口
}
// axios.defaults.baseURL = import.meta.env.VITE_APP_ENV === "development" ? import.meta.env.VITE_APP_BASE_URL : config.baseUrl; // 服务器接口地址前缀const token = () => {// 判断token是否存在函数const storedToken = localStorage.getItem("token");// console.log("token:", localStorage.getItem("token"));if (storedToken) {return storedToken;} else {// console.warn("Token 不存在!");return ""; // 或者返回 null,具体视后端需求而定}
};const getCookie = (name: string) => {const value = `; ${document.cookie}`;const parts = value.split(`; ${name}=`);if (parts.length === 2) return parts.pop().split(';').shift();
};//请求拦截
axios.interceptors.request.use((config) => {// 配置请求头config.headers["Content-Type"] = "application/json;charset=UTF-8";const authToken = token();if (authToken) {config.headers["Authorization"] = authToken;} else {// console.warn("请求头中未包含 Token");}//配置令牌等return config;},(error) => {return Promise.reject(error);}
);// 响应拦截
axios.interceptors.response.use((response: any) => {// console.log('响应成功:', response.request.responseURL);// console.log('响应成功:', response.data.code);// 判断token是否过期if (response) {// 假设当token过期时,后端返回内容中的code为997(根据后端实际情况而定)if (response.data.code === 997 && response.request.responseURL.slice(-5) !== 'login') {// 未授权,通常是 Token 过期或无效ElMessage.error("登录状态已过期,请重新登录!");localStorage.removeItem("token");// 写登录过期的处理代码,例如返回登陆页面router.push('/login');}}return response; // 确保返回整个响应对象,或根据需求返回 response.data},(error: any) => {if (error.response) {// 状态码不是 2xx// console.error('响应错误:', error.response);showMessage(error.response.status);return Promise.reject(error.response.data || error.response);} else if (error.request) {// 请求已发送,但没有收到响应// console.error('请求未收到响应:', error.request);ElMessage.warning("网络连接异常,请检查您的网络设置或稍后再试!");return Promise.reject(error.request);} else {// 其他错误// console.error('未知错误:', error.message);ElMessage.error("请求过程中发生未知错误,请稍后再试!");return Promise.reject(error.message || 'Unknown Error');}}
);export function request(config: { method: string, url: string, data?: any, params?: any }) {// console.log('发送请求:', config);return axios(config).then((response: any) => {// console.log('收到响应:', response);return response.data; // 或根据需求返回整个响应对象}).catch((err: any) => {console.error('请求失败:', err);return Promise.reject(err);});
}
2.使用token配置请求头解释
当请求数据时,后端需要判断用户的登录是否过期,通常除了登录接口外,在请求其他接口时都用token作为请求头发送给后端
3.token(登录)过期解释
本人这边,后端如果返回内容中的code为997,那就代表token过期,在这里可以做清除token及其他用户信息处理,并前往登录页面/login
4.自动判断运行环境,并采用不同的访问接口解释
可通过打印以下内容,查看当前项目的运行环境及在使用的访问地址情况
console.log('当前环境', import.meta.env.VITE_APP_ENV);console.log('地址', import.meta.env.VITE_APP_BASE_URL);
在第3步中,我们创建了2个代表不同环境的文件,分别配置了不同环境下使用的访问地址,可根据需要写接口,也可以用第3步.env文件配置的接口
5.在其他文件引入和使用封装好的axios请求
1.文件夹结构例子,在login.ts中引入和使用
创建login.ts 文件
2.引入和使用
import { request } from "@/utils/request"; // 引入axios请求方法// 登录
export function login(data: any) { // 使用方法return request({method: "post",// 请求方式url: `/vue/login`,// 接口,根据实际情况写data,// 请求参数});
}
3.在.vue文件中引入登录请求方法和使用
引入登录请求方法代码
import { login } from '@/api/login.ts'
发起请求代码
let para = {}// 请求参数
login(para).then((res: any) => {// res为返回内容
}).finally(() => {// 请求完成处理
})
欢迎学习和交流!