当前位置: 首页 > news >正文

vue+axios——创建多个实例共用请求拦截器和响应拦截器(403错误信息不提示bug解决)——基础积累

创建多个实例共用请求拦截器和响应拦截器:使用的是函数的继承,也就是call()方法,这个方法第一个参数就是this,后面的参数可以是一个也可以是多个。最后一定要记得要return出去,否则接口是拿不到数据的。

import axios from 'axios';
import Cookie from 'js-cookie';
const BASE_URL = process.env.VUE_APP_API_BASE_URL;
const BASE_URL_QUOTE = process.env.VUE_APP_API_BASE_URL_QUOTE;// 跨域认证信息 header 名
const xsrfHeaderName = 'Authorization';axios.defaults.timeout = 20000;
axios.defaults.withCredentials = false;
axios.defaults.xsrfHeaderName = xsrfHeaderName;
axios.defaults.xsrfCookieName = xsrfHeaderName;
axios.defaults.headers = {'accept-language':'zh-Hans'};
const request= axios.create({baseURL: BASE_URL,
});
const requestQuoteCenter= axios.create({baseURL: BASE_URL_QUOTE,
});
// http method
const METHOD = {GET: 'get',POST: 'post',PUT: 'put',DELETE: 'delete',
};/*** axios请求* @param url 请求地址* @param method {METHOD} http method* @param params 请求参数* @returns {Promise<AxiosResponse<T>>}*/async function requestQuoteCenter(url, method, params, config) {switch (method) {case METHOD.GET:return axios.get(url, { params, ...config });case METHOD.POST:return axios.post(url, params, config);case METHOD.PUT:return axios.put(url, params, config);case METHOD.DELETE:return axios.delete(url, { params, ...config });default:return axios.get(url, { params, ...config });}
}
async function request(url, method, params, config) {return await requestQuoteCenter.call(this, url, method, params, config);
}
/*** 加载 axios 拦截器* @param interceptors* @param options*/
function loadInterceptors(interceptors, options) {const { request, response } = interceptors;// 加载请求拦截器request.forEach((item) => {let { onFulfilled, onRejected } = item;if (!onFulfilled || typeof onFulfilled !== 'function') {onFulfilled = (config) => config;}if (!onRejected || typeof onRejected !== 'function') {onRejected = (error) => Promise.reject(error);}axios.interceptors.request.use((config) => onFulfilled(config, options),(error) => onRejected(error, options));});// 加载响应拦截器response.forEach((item) => {let { onFulfilled, onRejected } = item;if (!onFulfilled || typeof onFulfilled !== 'function') {onFulfilled = (response) => response;}if (!onRejected || typeof onRejected !== 'function') {onRejected = (error) => Promise.reject(error);}axios.interceptors.response.use((response) => onFulfilled(response, options),(error) => onRejected(error, options));});
}export {METHOD,request,loadInterceptors,requestQuoteCenter,
};

详细的请求和响应拦截器内容——分请求token认证校验+响应401和403校验

import Cookie from 'js-cookie';
const xsrfHeaderName = import.meta.env.VITE_TOKEN_NAME;
import { removeAuthorization } from '@/utils/request';// 401拦截
const resp401 = {/*** 响应数据之前做点什么* @param response 响应对象* @param options 应用配置 包含: {router, i18n, store, message}* @returns {*}*/onFulfilled(response, options) {const { message } = options;if (response.code === 401) {message.error('无此权限');}return response;},/*** 响应出错时执行* @param error 错误对象* @param options 应用配置 包含: {router, i18n, store, message}* @returns {Promise<never>}*/onRejected(error, options) {const { router, message } = options;if (error.response && error.response.status == 401) {message.error('认证 token 已过期,请重新登录');Cookie.remove(xsrfHeaderName);removeAuthorization();router.push('/login');return Promise.reject(error);}let msg = '';if (error.response && error.response.data && error.response.data.error_description) {msg = error.response.data.error_description;} else if (error.response && error.response.data && error.response.data.error) {msg = error.response.data.error.message;} else {msg = error.message;}message.error(msg);return Promise.reject(error);},
};const resp403 = {onFulfilled(response, options) {const { message } = options;if (response.code === 403) {message.error('请求被拒绝');}return response.data;},// onRejected(error, options) {//   const {message} = options//   const {response} = error//   if (response.status === 403) {//     message.error('请求被拒绝')//   }//   return Promise.reject(error)// }
};const reqCommon = {/*** 发送请求之前做些什么* @param config axios config* @param options 应用配置 包含: {router, i18n, store, message}* @returns {*}*/onFulfilled(config, options) {const { router, message } = options;const { url, xsrfCookieName, headers } = config;// if (url.indexOf('login') === -1 && xsrfCookieName && !Cookie.get(xsrfCookieName)) {//   message.warning('认证 token 已过期,请重新登录')// }if (headers.Authorization && xsrfCookieName && !Cookie.get(xsrfCookieName)) {message.warning('认证 token 已过期,请重新登录');}if (!headers.__tenant) {config.headers['Authorization'] = Cookie.get(xsrfHeaderName);} else {delete config.headers.Authorization;}return config;},/*** 请求出错时做点什么* @param error 错误对象* @param options 应用配置 包含: {router, i18n, store, message}* @returns {Promise<never>}*/onRejected(error, options) {const { message } = options;let msg = '';if (error.response && error.response.data) {msg = error.response.data.error;} else {msg = error.message;}message.error(msg);return Promise.reject(error);},
};export default {request: [reqCommon], // 请求拦截response: [resp401, resp403], // 响应拦截
};

上面两个文件合并后的处理如下:
main.js中添加如下内容:

import { loadInterceptors } from '@/utils/request';
import interceptors from '@/utils/axios-interceptors';
loadInterceptors(interceptors, {router, store, i18n, message})

403报错时,错误信息不提示的问题——解决办法

今天发现一个问题,如果是接口报403错误时,通过接口调用的时候,是无法获取到错误信息的。

之前的调用接口的方法就是:

import {request,METHOD} from './request.js';//就是从上面第一个文件导出的参数中获取到request
export function del(id) {return request(`/api/app/article/${id}`, METHOD.DELETE)
}

1.403不报错的解决办法(1)——通过async await的方式来处理接口

import {request,METHOD} from './request.js';//就是从上面第一个文件导出的参数中获取到request
export async function del(id) {return await request(`/api/app/article/${id}`, METHOD.DELETE)
}

2.403不报错的解决办法(2)——接口请求后的方法async await的处理方法

import {request} from './request.js';//就是从上面第一个文件导出的参数中获取到request
async customRequest(file) {let formData = new FormData();formData.append('file', file.file);let resp = await request(this.baseUrl, 'post', formData);//此时,如果接口调用失败,则会抛出错误提示信息,否则会执行下面的代码了this.$emit('uploadSucc', resp.Data);
},
http://www.lryc.cn/news/151865.html

相关文章:

  • 全球免费编程教育网站:Code.org
  • 构造函数与成员变量初始化
  • 使用Go env命令设置Go的环境
  • 目标检测YOLO实战应用案例100讲-道路场景下目标检测与分割模型的压缩研究与实现(续)
  • b站手机缓存文件转MP4
  • 一个集成的BurpSuite漏洞探测插件1.2
  • [FMMPEG] parse与 demuxer
  • 【Bug】Ubuntu 有线设置打不开无反应
  • 迈向无限可能, ATEN宏正领跑设备切换行业革命!
  • Ubuntu18.04:ORB-SLAM3使用数据集构建地图和保存点云地图
  • 找到自制电子杂志的方法了,快来看看?
  • Django请求的生命周期
  • Kotlin 中 OkHttp 使用及解析
  • 【C++代码】用栈实现队列,用队列实现栈--代码随想录
  • 肖sir__linux详解__001
  • 【Android Framework系列】第12章 RecycleView相关原理及四级缓存策略分析
  • P1886 滑动窗口 /【模板】(双端队列)+双端队列用法
  • 网络渗透day6-面试01
  • Docker 及 Docker Compose 安装指南
  • Gitlab创建一个空项目
  • C语言-内存分布(STM32内存分析)
  • Linux上配置NAT
  • springboot实现简单的消息对话
  • 「Tech初见」Linux驱动之blkdev
  • ssh配置(二、登录服务器)
  • pytorch异常——RuntimeError:Given groups=1, weight of size..., expected of...
  • 【FPGA项目】沙盘演练——基础版报文收发
  • 【C++技能树】继承概念与解析
  • 计算机网络 第二节
  • 无涯教程-机器学习 - 矩阵图函数