搭建VUE项目时,需要考虑封装一个全局的接口请求文件,可以对登录进行拦截以及请求的拦截,还有对通用的状态错误码和异常进行处理,这样外部使用接口请求时代码会很简洁。
以下是在网上找到的一个封装接口文件的参考demo,是对axios库的二次封装:
import axios from "axios";import { message } from "ant-design-vue";import router from "../router";/** * 提示函数 * 禁止点击蒙层、显示一秒后关闭 */const tip = (msg) => { message({ message: msg, duration: 1000, });};/** * 跳转登录页 * 携带当前页面路由,以期在登录页面完成登录后返回当前页面 */const toLogin = () => { router.replace({ path: "/login", });};// 创建axios实例const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url // withCredentials: true, // send cookies when cross-domain requests timeout: 5000, // request timeout});// 设置post请求头service.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";// 请求拦截器service.interceptors.request.use( (config) => { // 登录流程控制中,根据本地是否存在token判断用户的登录情况 // 但是即使token存在,也有可能token是过期的,所以在每次的请求头中携带token // 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码 // 而后我们可以在响应拦截器中,根据状态码进行一些统一的操作。 const token = localStorage.getItem("token"); token && (config.headers.Authorization = token); return config; }, (error) => { // 处理请求错误 return Promise.reject(error); });// 响应拦截器service.interceptors.response.use( //请求成功 (response) => { const res = response.data; if (res.code !== 200 && res.status !== 200) { return Promise.reject(res); } else { return res; } }, //请求失败 (error) => { const { response } = error; if (response) { // 请求已发出,但是不在30分钟的范围 errorHandle(response.status, response.data.message); return Promise.reject(response); } else { // 处理断网的情况 // eg:请求超时或断网时,更新state的network状态 // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏 // 关于断网组件中的刷新重新获取数据,会在断网组件中说明 // store.commit('changeNetwork', false); } });/** * 请求失败后的错误统一处理 * @param {Number} status 请求失败的状态码 */const errorHandle = (status) => { // 状态码判断 switch (status) { // 401: 未登录状态,跳转登录页 case 401: toLogin(); break; // 403 token过期 // 清除token并跳转登录页 case 403: localStorage.removeItem("token"); message({ message: "登录过期,请重新登录", callback: (action) => { console.log("action", action); toLogin(); }, }); break; // 404请求不存在 case 404: tip("请求的资源不存在"); break; }};export default service;
以下是我们项目组实际使用的request文件,axios + antDesignVue组件库。
首先,需要在utils目录下新增一个request.js文件: import Vue from "vue";import store from "../store/demo";import router from "../router";import axios from "axios";import { message } from "ant-design-vue";const vm = new Vue({ store, router });let baseURL = "";const service = axios.create({ baseURL: baseURL, timeout: 120000,});// 请求拦截service.interceptors.request.use( (config) => { config.headers["Content-type"] = "application/json; charset=utf-8;"; vm.$store.dispatch("global/setLoading", true); return config; }, (error) => { console.log("error", error); return Promise.reject(error); });// 响应拦截service.interceptors.response.use( (response) => { const status = response.status; const code = response.data.status || response.data.code; const res = response.data; vm.$store.dispatch("global/setLoading", false); if (status === 200) { // 处理登录失败 const toLoginCode = ["00211", "00212"]; if (toLoginCode.indexOf(code) !== -1) { sessionStorage.removeItem("token"); router.push({ path: "/to-login" }); return res; } // 处理成功 const successCode = ["I0000", "I0001"]; if (successCode.indexOf(code) !== -1) { return res; } // 处理失败 const errCode = ["Err001", "Err002", "Err003"]; if (errCode.indexOf(code) !== -1) { message.error(res.msg || "服务器异常,请稍后重试!"); } return Promise.reject(res); } else { return Promise.reject(new Error(res.msg || "Error")); } }, (error) => { vm.$store.dispatch("global/setLoading", false); let status; try { status.error.response.status; } catch (error) { status = 500; } message.error(`服务器异常,请稍后重试。当前状态码:${status}`); return Promise.reject(error); });
其次,需要在API目录下,新建一个如homeApi.js的文件: // 引入刚刚创建的接口请求文件import fetch from "../utils/request.js"; // 全局请求的参数,如userId, token等,没有可忽略import { public } from "@/api/public.config.js";// 接口地址,判断测试、开发、生产import { baseUrl } from "@/config/baseUrl.config.js";export const login = (data)=>{ fetch(url:`${baseUrl}/server/login`, method: 'post',data:{public: public(),private:data })}
最后,页面上的具体使用实例: // 引入用到的接口:import { login } from ’@/api/homeApi‘// 简单示例:setLogin(){ login().then(res=>{ console.log(res) })}//复杂示例:setLogin(info){ const params = { userName: info } login(params ).then(res=>{ console.log(res) // res.status === 'I0000' 是后端定义连接成功的状态码 if(res.status === 'I0000'){ const { list, total} = res this.list = list } })}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |