④ 版本② 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 ...
随机推荐
- python37
Python 循环嵌套 Python 语言允许在一个循环体里面嵌入另一个循环. Python for 循环嵌套语法: for iterating_var in sequence: for iterat ...
- raid 0 与raid 1的区别?
区别共有三点: 1.两者的概念不同: RAID 0:是多磁盘数据分组同步写读. RAID 1:是多磁盘同数据同步写读. 2.两者的安全性不同: RAID 0:无数据备份功能,安全性差. RAID 1: ...
- 阿里云部署OSS对接TP项目
1.配置文件写入参数 domain为阿里云oss存储实例要绑定的域名 2.获取accesskeyId和secret 注册用户 出现下图,选择"开始使用子用户Access Key" ...
- 重试机制的实现(Guava Retry)
重试机制的实现 重试作用: 对于重试是有场景限制的,参数校验不合法.写操作等(要考虑写是否幂等)都不适合重试. 远程调用超时.网络突然中断可以重试.外部 RPC 调用,或者数据入库等操作,如果一次操作 ...
- 网络很慢mtu设置
[root@db-***** etc]# cat /etc/rc.local #!/bin/sh # # This script will be executed *after* all the ot ...
- vite vue插件打包配置
import { defineConfig, UserConfigExport, ConfigEnv } from "vite"; import externalGlobals f ...
- Source Tree 1、解决打开闪退问题2、解决找不到项目的问题
闪退问题主要做了两点 1.版本降到3.1.2 下载链接:Sourcetree Download Archives | Sourcetree 2.参考博客做出文件修改参考bigbig猿博客 新建json ...
- spring注解SQL注意事项
目前有两个类:机构.职员 package com.common.vo; public class Org{ public long id; public String name; public Str ...
- Docker之RabbitMQ保姆级别安装
Docker之RabbitMQ保姆级别安装: 如果觉得样式不好:跳转即可 http://www.lifengying.site/(md文件复制过来有些样式会不一样) 学英语网站项目:自己先保证Redi ...
- iOS 扩展与分类的区别
1.分类 category 分类的作用就是在不修改原有类的基础上,为一个类扩展方法,最主要的是可以给系统类扩展我们自己定义的方法 分类也能使用@property 添加属性 [通过runtime 关联对 ...