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 封装的更多相关文章

  1. 把axios封装为vue插件使用

    前言 自从Vue2.0推荐大家使用 axios 开始,axios 被越来越多的人所了解.使用axios发起一个请求对大家来说是比较简单的事情,但是axios没有进行封装复用,项目越来越大,引起的代码冗 ...

  2. 原生js上传图片遇到的坑(axios封装)

    后台给我写了一个上传图片的接口,自己用form表单测试成功 接口可以正常跳转 测试的代码: <!doctype html> <html lang="en"> ...

  3. vue3.0+vite+ts项目搭建-axios封装(六)

    封装方式一 import axios from 'axios' import qs from 'qs' import { Toast } from 'vant' import Lockr from ' ...

  4. axios封装

    前言 作为出入vue的小萌新,我在写请求的时候,也是毫不犹豫写了ajax,结果肯定是不行的... Vue 原本有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2. ...

  5. vue2.0 axios封装、vuex介绍

    一.前言 博主也是vue道路上的行者,道行不深,希望自己的东西能对大家有所帮助.这篇博客针对 了解过vue基础,但是没有做过vue项目的童鞋.如果想看基础指令,可以看我之前的一篇博客,请点击  跳转, ...

  6. vue项目搭建 (二) axios 封装篇

    vue项目搭建 (二) axios 封装篇 项目布局 vue-cli构建初始项目后,在src中进行增删修改 // 此处是模仿github上 bailicangdu 的 ├── src | ├── ap ...

  7. vue-cli3中axios如何跨域请求以及axios封装

    1. vue.config.js中配置如下 module.exports = { // 选项... // devtool: 'eval-source-map',//开发调试 devServer: { ...

  8. axios interceptors 拦截 , 页面跳转, token 验证 Vue+axios实现登陆拦截,axios封装(报错,鉴权,跳转,拦截,提示)

    Vue+axios实现登陆拦截,axios封装(报错,鉴权,跳转,拦截,提示) :https://blog.csdn.net/H1069495874/article/details/80057107 ...

  9. 【Vue】axios封装,更好的管理api接口和使用

    在现在的前端开发中,前后端分离开发比较主流,所以在封装方法和模块化上也是非常需要掌握的一门技巧.而axios的封装也是非常的多,下面的封装其实跟百度上搜出来的axios封装或者axios二次封装区别不 ...

  10. vue axios 封装(二)

    封装二: http.js import axios from 'axios' import storeHelper from './localstorageHelper' // 全局设置 const ...

随机推荐

  1. tool script to convert back slash

    Back slash is used in windows, which makes so many headache for me. Then an idea came to my mind. It ...

  2. Vue2 element-ui组件二封-表单组件-效果展示

    vue2已经落后了? 不着急, vue3的也在写的过程中, 只是发出来vue2的一些组件 系列说明: > 编写原因 vue2在很多人眼里已经快过时了, 而我一直想写一些总结, 但是从两年前到现在 ...

  3. gson TypeAdapter 和FieldNamingStrategy,SerializedName实现属性名称的设置别名

    gson TypeAdapter 和FieldNamingStrategy,SerializedName实现属性名称的设置别名 package com.example.core.mydemo.Type ...

  4. pycharm永久激活码(亲测好用)

    引用自某不知名大佬,在此致谢,获取激活码链接如下: https://www.ajihuo.com/pycharm/4197.html

  5. 集群分发xsync xcall kafka启动脚本命令,命令方式安装epel源

    安装epel库源 yum install epel-release -y --nogpgcheck yum install glances 安装开始 建立hosts 白名单 127.0.0.1 loc ...

  6. centos6根分区扩容,非lvm

    1.关闭虚拟机,删除里面的快照,将磁盘扩容 2.根分区为sda3,开机后输入fdisk /dev/sda,d,3删除sda3,然后n,p,3,w创建sda3,扇区的开始位置要一致 3.growpart ...

  7. es 部署 进程、文件数 配置

    1.  /etc/security/limits.conf elasticsearch soft nofile 65536 elasticsearch hard nofile 65536 elasti ...

  8. ObjectARX2016-1打印HelloWolrd

    首先把Objectarx2016和VS2012安装好,安装好之后,如果在VS2012创建项目的过程中出现创建项目失败的情况,可以查看我的第一篇随笔https://www.cnblogs.com/Arc ...

  9. 域名证书https配置问题

    目前默认通配证书只适配2级通配.例如配置2级域名的通配证书 https://a.baidu.com.如果想配置三级域名的https 需购买3级通配证书.这样才可以配置三级域名. https://a.b ...

  10. Dinic的几种复杂度

    学了那么久网络流才发现自己不知道 Dinic 算法的一个在各边容量均为 \(1\) 的网络时复杂度上的结论.我说为啥学术社区那题优化建图复杂度是对的呢-- 以下均认为使用了当前弧优化与多路增广. 以下 ...