创建多个实例共用请求拦截器和响应拦截器:使用的是函数的继承,也就是
call()
方法,这个方法第一个参数就是this
,后面的参数可以是一个也可以是多个。最后一定要记得要return
出去,否则接口是拿不到数据的。
axios创建多个实例共用
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) {
return await request.call(this,requestQuoteCenter, url, method, params, config);
}
async function request(axios,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 });
}
}
/**
* 加载 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);
},
下面的内容跟文章相关不大,只是为了凑字数,可忽略!!!
1.Axios简介
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中
axios的github: https://github.com/axios/axios
Axios 是一个基于 promise 的 HTTP 库,简单的讲就是可以发送get、post等请求,可以用在浏览器和 node.js 中。React等框架的出现,促使了Axios轻量级库的出现,因为Vue等,不需要操作Dom,所以不需要引入Jquery.js了。
promise
异步编程的一种解决方案
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
Promise提供统一的API,各种异步操作都可以用同样的方法进行处理
Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态 (英语意思就是“承诺”,表示其他手段无法改变)
与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。 有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数文章来源:https://www.toymoban.com/news/detail-692108.html
2.特性
从浏览器创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求和响应数据
取消请求
自动转换JSON数据
客户端支持防御XSRF文章来源地址https://www.toymoban.com/news/detail-692108.html
到了这里,关于vue+axios——创建多个实例共用请求拦截器和响应拦截器(403错误信息不提示bug解决)——基础积累的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!