HttpRequestBase 类

1 构造函数

  1. constructor(baseUrl) {
  2. const basePort = getUrlPort(baseUrl);
  3. this.baseUrl = baseUrl;
  4. this.baseUrlWithPort2 = baseUrl.replace(/(\/\/.*:)(\d+)/, `$1${basePort + 1}`);
  5. this.basePort = basePort; // 原始端口
  6. this.queue = {};
  7. this.triggerTime = '';
  8. this.alikeUrl = []; // ajax标识--请求地址&请求方式
  9. this.CancelToken = axios.CancelToken;
  10. // 在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
  11. this.removeAlikeUrl = config => {
  12. // 截取 baseUrl 后的字符串
  13. let configUrl =
  14. config.url.indexOf(config.baseURL) !== -1
  15. ? config.url.substring(config.baseURL.length, config.url.length)
  16. : config.url;
  17. for (var i = this.alikeUrl.length - 1; i >= 0; i--) {
  18. if (this.alikeUrl[i].u === configUrl + '&' + config.method) {
  19. this.alikeUrl[i].cancel('axios请求被取消');
  20. this.alikeUrl.splice(i, 1);
  21. break;
  22. }
  23. }
  24. };
  25. }

2 事件处理程序

2.1 请求封装

  1. request(options) {
  2. // 创建 axios 请求
  3. const instance = axios.create();
  4. // 请求参数处理
  5. options = this.getInsideConfig(options);
  6. // 请求响应拦截
  7. this.interceptors(instance, options.url);
  8. return instance(options);
  9. }

2.2 请求参数处理

  • transformRequest 允许在向服务器发送前修改请求数据,只能用put post patch请求方法
  1. getFinalBaseURL(apiUrl) {
  2. return checkIsUsePort2(apiUrl, this.basePort) ? this.baseUrlWithPort2 : this.baseUrl;
  3. }
  4. getInsideConfig(options) {
  5. const config = {
  6. baseURL: this.getFinalBaseURL(options.url),
  7. headers: {
  8. 'Content-Type': 'application/x-www-form-urlencoded',
  9. Authorization: SessionIdConfigure.getLocalId()
  10. },
  11. // 在向服务器发送前修改请求数据
  12. transformRequest: [
  13. data => {
  14. let ret = '';
  15. for (var i in data) {
  16. if (data[i] instanceof Array) {
  17. for (var j in data[i]) {
  18. ret += i + '=' + (
  19. typeof data[i][j] === 'object'
  20. ? JSON.stringify(data[i][j])
  21. : encodeURIComponent(data[i][j])
  22. ) + '&';
  23. }
  24. } else {
  25. if (
  26. !(String(data[i]) === 'null' || String(data[i]) === 'undefined') &&
  27. String(data[i]).indexOf('NaN-aN-aN') === -1
  28. ) {
  29. ret += i + '=' + encodeURIComponent(data[i]) + '&';
  30. } else {
  31. ret += i + '=&';
  32. }
  33. }
  34. }
  35. return ret;
  36. }
  37. ],
  38. ...options
  39. }
  40. return config;
  41. }

2.3 取消loading效果

  1. destroy(url) {
  2. if (this.queue[url]) delete this.queue[url];
  3. if (!Object.keys(this.queue).length) {
  4. store.commit('appLoading/display', false);
  5. }
  6. }

2.4 请求响应拦截处理

  1. interceptors(instance, url) {
  2. let isNoSpin = proStorage.fetch('noSpin');
  3. isNoSpin && proStorage.save('noSpin', 'false');
  4. // 请求拦截
  5. // 响应拦截
  6. }
  • 请求拦截
  1. /**
  2. * 请求拦截
  3. * @property {Function} config.cancelTrigger 可传入自定义请求取消方法
  4. */
  5. instance.interceptors.request.use(
  6. config => {
  7. this.removeAlikeUrl(config); //在一个ajax发送前执行一下取消操作
  8. let cancelTrigger = config.cancelTrigger;
  9. if (!config.cancelTrigger) {
  10. config.cancelToken = new this.CancelToken(c => {
  11. cancelTrigger = c;
  12. });
  13. }
  14. // ajax标识--请求地址&请求方式
  15. this.alikeUrl.push({ u: config.url + '&' + config.method, cancel: cancelTrigger });
  16. // 触发时间
  17. this.triggerTime = new Date();
  18. // 添加全局的loading...
  19. if (!Object.keys(this.queue).length && (!isNoSpin || isNoSpin === 'false')) {
  20. store.commit('appLoading/display', true);
  21. }
  22. if (!isNoSpin || isNoSpin === 'false') {
  23. this.queue[url] = true;
  24. }
  25. isNoSpin = null;
  26. return config;
  27. },
  28. error => {
  29. return Promise.reject(error);
  30. }
  31. );
  • 响应拦截
  1. instance.interceptors.response.use(
  2. res => {
  3. // 在一个ajax响应后再执行一下取消操作
  4. this.removeAlikeUrl(res.config);
  5. this.destroy(url);
  6. const { data, status } = res;
  7. const {
  8. config: { method }
  9. } = JSON.parse(JSON.stringify(res));
  10. if (
  11. store.state.interfaceLog.storageLog.developmentOff &&
  12. url.indexOf('analysis/api/') !== -1 &&
  13. method === 'post' &&
  14. data.code === 1
  15. ) {
  16. let query_key, query_name, query_time, exec_time;
  17. if (data.data && Object.keys(data.data).length > 0) {
  18. query_key = data.data['query_key'];
  19. query_name = data.data['query_name'];
  20. query_time = data.data['query_time'];
  21. exec_time = data.data['exec_time'];
  22. } else if (data.os_data && data.os_data[0] && Object.keys(data.os_data[0]).length > 0) {
  23. query_key = data.os_data[0].data['query_key'];
  24. query_name = data.os_data[0].data['query_name'];
  25. query_time = data.os_data[0].data['query_time'];
  26. exec_time = data.os_data[0].data['exec_time'];
  27. }
  28. const logData = {
  29. url,
  30. query_key,
  31. query_name,
  32. query_time,
  33. exec_time,
  34. title: router.currentRoute.meta.title,
  35. param: res.config.data,
  36. triggerTime: this.triggerTime,
  37. msg: data.msg
  38. };
  39. store.commit('addStorageLog', logData);
  40. }
  41. interceptResponse(data.code);
  42. return { data, status };
  43. },
  44. error => {
  45. this.destroy(url);
  46. console.error('response: ', typeof error === 'object' ? error.message : error);
  47. if (!axios.isCancel(error)) {
  48. this.removeAlikeUrl(error.config);
  49. let errorInfo = error.response;
  50. if (!errorInfo) {
  51. const {
  52. request: { statusText, status },
  53. config
  54. } = error;
  55. errorInfo = {
  56. statusText,
  57. status,
  58. request: { responseURL: config.url }
  59. };
  60. }
  61. interceptResponse(errorInfo.status);
  62. }
  63. return Promise.reject(error);
  64. }
  65. );

2.5 类外方法

  • 请求过期提示
  1. function interceptResponse(status) {
  2. if (status === 401 && router.currentRoute.name !== 'Login') {
  3. Modal.warning({
  4. title: '提示',
  5. content: 'Session已过期!请您确认返回登录页面重新登录!',
  6. onOk: () => {
  7. store.commit('user/logout');
  8. }
  9. })
  10. }
  11. }
  • 是否使用第二端口
  1. // 以 /analysis 和 /query 开头的接口需切换端口,现在的匹配模式包含了前后的'/'符号
  2. function checkIsUsePort2(url, basePort) {
  3. return (basePort === 9001 || basePort >= 30000) && /^\/(analysis|query)[^/]*\//.test(url);
  4. }
  • 获取地址端口号
  1. function getUrlPort(url) {
  2. let result = url.match(/\/\/.*:(\d+)/);
  3. return result && Number(result[1]);
  4. }

④ 版本② 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. python37

    Python 循环嵌套 Python 语言允许在一个循环体里面嵌入另一个循环. Python for 循环嵌套语法: for iterating_var in sequence: for iterat ...

  2. raid 0 与raid 1的区别?

    区别共有三点: 1.两者的概念不同: RAID 0:是多磁盘数据分组同步写读. RAID 1:是多磁盘同数据同步写读. 2.两者的安全性不同: RAID 0:无数据备份功能,安全性差. RAID 1: ...

  3. 阿里云部署OSS对接TP项目

    1.配置文件写入参数 domain为阿里云oss存储实例要绑定的域名 2.获取accesskeyId和secret 注册用户 出现下图,选择"开始使用子用户Access Key" ...

  4. 重试机制的实现(Guava Retry)

    重试机制的实现 重试作用: 对于重试是有场景限制的,参数校验不合法.写操作等(要考虑写是否幂等)都不适合重试. 远程调用超时.网络突然中断可以重试.外部 RPC 调用,或者数据入库等操作,如果一次操作 ...

  5. 网络很慢mtu设置

    [root@db-***** etc]# cat /etc/rc.local #!/bin/sh # # This script will be executed *after* all the ot ...

  6. vite vue插件打包配置

    import { defineConfig, UserConfigExport, ConfigEnv } from "vite"; import externalGlobals f ...

  7. Source Tree 1、解决打开闪退问题2、解决找不到项目的问题

    闪退问题主要做了两点 1.版本降到3.1.2 下载链接:Sourcetree Download Archives | Sourcetree 2.参考博客做出文件修改参考bigbig猿博客 新建json ...

  8. spring注解SQL注意事项

    目前有两个类:机构.职员 package com.common.vo; public class Org{ public long id; public String name; public Str ...

  9. Docker之RabbitMQ保姆级别安装

    Docker之RabbitMQ保姆级别安装: 如果觉得样式不好:跳转即可 http://www.lifengying.site/(md文件复制过来有些样式会不一样) 学英语网站项目:自己先保证Redi ...

  10. iOS 扩展与分类的区别

    1.分类 category 分类的作用就是在不修改原有类的基础上,为一个类扩展方法,最主要的是可以给系统类扩展我们自己定义的方法 分类也能使用@property 添加属性 [通过runtime 关联对 ...