④ 版本② axios 封装
HttpRequestBase 类
1 构造函数
constructor(baseUrl) {
const basePort = getUrlPort(baseUrl);
this.baseUrl = baseUrl;
this.baseUrlWithPort2 = baseUrl.replace(/(\/\/.*:)(\d+)/, `$1${basePort + 1}`);
this.basePort = basePort; // 原始端口
this.queue = {};
this.triggerTime = '';
this.alikeUrl = []; // ajax标识--请求地址&请求方式
this.CancelToken = axios.CancelToken;
// 在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
this.removeAlikeUrl = config => {
// 截取 baseUrl 后的字符串
let configUrl =
config.url.indexOf(config.baseURL) !== -1
? config.url.substring(config.baseURL.length, config.url.length)
: config.url;
for (var i = this.alikeUrl.length - 1; i >= 0; i--) {
if (this.alikeUrl[i].u === configUrl + '&' + config.method) {
this.alikeUrl[i].cancel('axios请求被取消');
this.alikeUrl.splice(i, 1);
break;
}
}
};
}
2 事件处理程序
2.1 请求封装
request(options) {
// 创建 axios 请求
const instance = axios.create();
// 请求参数处理
options = this.getInsideConfig(options);
// 请求响应拦截
this.interceptors(instance, options.url);
return instance(options);
}
2.2 请求参数处理
transformRequest允许在向服务器发送前修改请求数据,只能用put post patch请求方法
getFinalBaseURL(apiUrl) {
return checkIsUsePort2(apiUrl, this.basePort) ? this.baseUrlWithPort2 : this.baseUrl;
}
getInsideConfig(options) {
const config = {
baseURL: this.getFinalBaseURL(options.url),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: SessionIdConfigure.getLocalId()
},
// 在向服务器发送前修改请求数据
transformRequest: [
data => {
let ret = '';
for (var i in data) {
if (data[i] instanceof Array) {
for (var j in data[i]) {
ret += i + '=' + (
typeof data[i][j] === 'object'
? JSON.stringify(data[i][j])
: encodeURIComponent(data[i][j])
) + '&';
}
} else {
if (
!(String(data[i]) === 'null' || String(data[i]) === 'undefined') &&
String(data[i]).indexOf('NaN-aN-aN') === -1
) {
ret += i + '=' + encodeURIComponent(data[i]) + '&';
} else {
ret += i + '=&';
}
}
}
return ret;
}
],
...options
}
return config;
}
2.3 取消loading效果
destroy(url) {
if (this.queue[url]) delete this.queue[url];
if (!Object.keys(this.queue).length) {
store.commit('appLoading/display', false);
}
}
2.4 请求响应拦截处理
interceptors(instance, url) {
let isNoSpin = proStorage.fetch('noSpin');
isNoSpin && proStorage.save('noSpin', 'false');
// 请求拦截
// 响应拦截
}
- 请求拦截
/**
* 请求拦截
* @property {Function} config.cancelTrigger 可传入自定义请求取消方法
*/
instance.interceptors.request.use(
config => {
this.removeAlikeUrl(config); //在一个ajax发送前执行一下取消操作
let cancelTrigger = config.cancelTrigger;
if (!config.cancelTrigger) {
config.cancelToken = new this.CancelToken(c => {
cancelTrigger = c;
});
}
// ajax标识--请求地址&请求方式
this.alikeUrl.push({ u: config.url + '&' + config.method, cancel: cancelTrigger });
// 触发时间
this.triggerTime = new Date();
// 添加全局的loading...
if (!Object.keys(this.queue).length && (!isNoSpin || isNoSpin === 'false')) {
store.commit('appLoading/display', true);
}
if (!isNoSpin || isNoSpin === 'false') {
this.queue[url] = true;
}
isNoSpin = null;
return config;
},
error => {
return Promise.reject(error);
}
);
- 响应拦截
instance.interceptors.response.use(
res => {
// 在一个ajax响应后再执行一下取消操作
this.removeAlikeUrl(res.config);
this.destroy(url);
const { data, status } = res;
const {
config: { method }
} = JSON.parse(JSON.stringify(res));
if (
store.state.interfaceLog.storageLog.developmentOff &&
url.indexOf('analysis/api/') !== -1 &&
method === 'post' &&
data.code === 1
) {
let query_key, query_name, query_time, exec_time;
if (data.data && Object.keys(data.data).length > 0) {
query_key = data.data['query_key'];
query_name = data.data['query_name'];
query_time = data.data['query_time'];
exec_time = data.data['exec_time'];
} else if (data.os_data && data.os_data[0] && Object.keys(data.os_data[0]).length > 0) {
query_key = data.os_data[0].data['query_key'];
query_name = data.os_data[0].data['query_name'];
query_time = data.os_data[0].data['query_time'];
exec_time = data.os_data[0].data['exec_time'];
}
const logData = {
url,
query_key,
query_name,
query_time,
exec_time,
title: router.currentRoute.meta.title,
param: res.config.data,
triggerTime: this.triggerTime,
msg: data.msg
};
store.commit('addStorageLog', logData);
}
interceptResponse(data.code);
return { data, status };
},
error => {
this.destroy(url);
console.error('response: ', typeof error === 'object' ? error.message : error);
if (!axios.isCancel(error)) {
this.removeAlikeUrl(error.config);
let errorInfo = error.response;
if (!errorInfo) {
const {
request: { statusText, status },
config
} = error;
errorInfo = {
statusText,
status,
request: { responseURL: config.url }
};
}
interceptResponse(errorInfo.status);
}
return Promise.reject(error);
}
);
2.5 类外方法
- 请求过期提示
function interceptResponse(status) {
if (status === 401 && router.currentRoute.name !== 'Login') {
Modal.warning({
title: '提示',
content: 'Session已过期!请您确认返回登录页面重新登录!',
onOk: () => {
store.commit('user/logout');
}
})
}
}
- 是否使用第二端口
// 以 /analysis 和 /query 开头的接口需切换端口,现在的匹配模式包含了前后的'/'符号
function checkIsUsePort2(url, basePort) {
return (basePort === 9001 || basePort >= 30000) && /^\/(analysis|query)[^/]*\//.test(url);
}
- 获取地址端口号
function getUrlPort(url) {
let result = url.match(/\/\/.*:(\d+)/);
return result && Number(result[1]);
}
④ 版本② axios 封装的更多相关文章
- 把axios封装为vue插件使用
前言 自从Vue2.0推荐大家使用 axios 开始,axios 被越来越多的人所了解.使用axios发起一个请求对大家来说是比较简单的事情,但是axios没有进行封装复用,项目越来越大,引起的代码冗 ...
- 原生js上传图片遇到的坑(axios封装)
后台给我写了一个上传图片的接口,自己用form表单测试成功 接口可以正常跳转 测试的代码: <!doctype html> <html lang="en"> ...
- vue3.0+vite+ts项目搭建-axios封装(六)
封装方式一 import axios from 'axios' import qs from 'qs' import { Toast } from 'vant' import Lockr from ' ...
- axios封装
前言 作为出入vue的小萌新,我在写请求的时候,也是毫不犹豫写了ajax,结果肯定是不行的... Vue 原本有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2. ...
- vue2.0 axios封装、vuex介绍
一.前言 博主也是vue道路上的行者,道行不深,希望自己的东西能对大家有所帮助.这篇博客针对 了解过vue基础,但是没有做过vue项目的童鞋.如果想看基础指令,可以看我之前的一篇博客,请点击 跳转, ...
- vue项目搭建 (二) axios 封装篇
vue项目搭建 (二) axios 封装篇 项目布局 vue-cli构建初始项目后,在src中进行增删修改 // 此处是模仿github上 bailicangdu 的 ├── src | ├── ap ...
- vue-cli3中axios如何跨域请求以及axios封装
1. vue.config.js中配置如下 module.exports = { // 选项... // devtool: 'eval-source-map',//开发调试 devServer: { ...
- axios interceptors 拦截 , 页面跳转, token 验证 Vue+axios实现登陆拦截,axios封装(报错,鉴权,跳转,拦截,提示)
Vue+axios实现登陆拦截,axios封装(报错,鉴权,跳转,拦截,提示) :https://blog.csdn.net/H1069495874/article/details/80057107 ...
- 【Vue】axios封装,更好的管理api接口和使用
在现在的前端开发中,前后端分离开发比较主流,所以在封装方法和模块化上也是非常需要掌握的一门技巧.而axios的封装也是非常的多,下面的封装其实跟百度上搜出来的axios封装或者axios二次封装区别不 ...
- vue axios 封装(二)
封装二: http.js import axios from 'axios' import storeHelper from './localstorageHelper' // 全局设置 const ...
随机推荐
- python34
Python成员运算符 除了以上的一些运算符之外,Python还支持成员运算符,测试实例中包含了一系列的成员,包括字符串,列表或元组. 运算符 描述 实例 in 如果在指定的序列中找到值返回 True ...
- CAD专用卸载工具,完美彻底卸载清除干净cad各种残留注册表和文件。
CAD专用卸载工具,完美彻底卸载清除干净cad各种残留注册表和文件.有的同学由于一些原因想把cad卸载掉然后重新安装,但是cad安装到一半就失败了或者显示已安装或者未完成,还有的同学会遇到" ...
- 蓝桥杯训练赛二-1169 问题 D: 绝对值排序
题目描述 输入n(n<=100)个整数,按照绝对值从大到小排序后输出.题目保证对于每一个测试实例,所有的数的绝对值都不相等. 输入 输入数据有多组,每组占一行,每行的第一个数字为n,接着是n个整 ...
- WSL2 网络异常排查 [ping 不通、网络地址异常、缺少默认路由、被宿主机防火墙拦截]
最近在使用的 wsl2 的时候突然发现 wsl2 无法正常联网,即 ping 不通外网以及宿主机的 wsl 网卡.但是将 wsl 版本设置为 1 就可以联网了. 如果你是正常使用的时候,并且自己没有手 ...
- vite2.9 + vue3.2 打包部署到nginx上刷新页面404问题
vite2.9 + vue3.2 打包部署到nginx上刷新页面404问题 在本地运行没问题,部署到服务器上,能正常访问,但是刷新之后页面404 原有的Nginx配置为: server { liste ...
- 2363. 合并相似的物品 (Easy)
问题描述 2363. 合并相似的物品 (Easy) 给你两个二维整数数组 items1 和 items2 ,表示两个物品集合.每个数组 items 有以下特质: items[i] = [valueᵢ, ...
- Linux环境使用Docker安装MySql
系统环境: CentOS 7.6 64位(同样适用于Ubuntu) 安装步骤: 1.创建文件夹 /home/docker/mysql/config /home/docker/mysql/data 2. ...
- Ajax后台传数组参数,接收不到报错!
var Gid = ""; var Name = ""; var strGid = []; var strName = []; for (var i = 0; ...
- 「DIARY」PKUSC 2021 游记
冬令营没了但是还有夏令营 (完蛋,前两天忘写游记了,完全没想起来--最后一天补一补) 试题分析在另外一篇博客上 # Day 0 早上去机场的时候把手机落在出租车上了 (还好之后找回来了),导致我前两天 ...
- postman收藏 -大佬玩法。
请求顺序: https://www.cnblogs.com/superhin/p/11454832.html 在Postman脚本中发送请求(pm.sendRequest) : https:// ...