axios

axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
在前端框架中的应用也是特别广泛,不管是vue还是react,都有很多项目用axios作为网络请求库。
我在最近的几个项目中都有使用axios,并基于axios根据常见的业务场景封装了一个通用的request服务。

业务场景:

  1. 全局请求配置。
  2. get,post,put,delete等请求的promise封装。
  3. 全局请求状态管理。
  4. 取消重复请求。
  5. 路由跳转取消当前页面请求。
  6. 请求携带token,权限错误统一管理。

默认配置


定义全局的默认配置

axios.defaults.timeout = 10000 //超时取消请求
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
axios.defaults.baseURL = process.env.BASE_URL //挂载在process下的环境常量,在我另一篇文章有详细说明

如何定义多环境常量


自定义配置(非常见业务场景,仅作介绍)

// 创建实例时设置配置的默认值
var instance = axios.create({baseURL: 'https://api.another.com'
});
// 在实例已创建后修改默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

优先级:自定义配置 > 默认配置

请求及响应拦截器

请求拦截器及取消重复请求

// 请求列表
const requestList = []
// 取消列表
const CancelToken = axios.CancelToken
let sources = {}
axios.interceptors.request.use((config) => {//将请求地址及参数作为一个完整的请求const request = JSON.stringify(config.url) + JSON.stringify(config.data)config.cancelToken = new CancelToken((cancel) => {sources[request] = cancel})//1.判断请求是否已存在请求列表,避免重复请求,将当前请求添加进请求列表数组;if(requestList.includes(request)){sources[request]('取消重复请求')}else{requestList.push(request)//2.请求开始,改变loading状态供加载动画使用store.dispatch('changeGlobalState', {loading: true})}//3.从store中获取token并添加到请求头供后端作权限校验const token = store.getters.userInfo.tokenif (token) {config.headers.token = token}return config
}, function (error) {return Promise.reject(error)
})

1.请求拦截器中将所有请求添加进请求列表变量,为取消请求及loading状态管理做准备;当请求列表已存在当前请求则不响应该请求。
2.请求一旦开始,就可以开启动画加载效果。
3.用户登录后可以在请求头中携带token做权限校验使用。


响应拦截器

axios.interceptors.response.use(function (response) {// 1.将当前请求中请求列表中删除const request = JSON.stringify(response.config.url) + JSON.stringify(response.config.data)requestList.splice(requestList.findIndex(item => item === request), 1)// 2.当请求列表为空时,更改loading状态if (requestList.length === 0) {store.dispatch('changeGlobalState', {loading: false})}// 3.统一处理权限认证错误管理if (response.data.code === 900401) {window.ELEMENT.Message.error('认证失效,请重新登录!', 1000)router.push('/login')}return response
}, function (error) {// 4.处理取消请求if (axios.isCancel(error)) {requestList.length = 0store.dispatch('changeGlobalState', {loading: false})throw new axios.Cancel('cancel request')} else {// 5.处理网络请求失败window.ELEMENT.Message.error('网络请求失败', 1000)}return Promise.reject(error)
})

1.响应返回后将相应的请求从请求列表中删除
2.当请求列表为空时,即所有请求结束,加载动画结束
3.权限认证报错统一拦截处理
4.取消请求的处理需要结合其他代码说明
5.由于项目后端并没有采用RESTful风格的接口请求,200以外都归为网络请求失败

promise封装

const request = function (url, params, config, method) {return new Promise((resolve, reject) => {axios[method](url, params, Object.assign({}, config)).then(response => {resolve(response.data)}, err => {if (err.Cancel) {console.log(err)} else {reject(err)}}).catch(err => {reject(err)})})
}const post = (url, params, config = {}) => {return request(url, params, config, 'post')
}const get = (url, params, config = {}) => {return request(url, params, config, 'get')
}
//3.导出cancel token列表供全局路由守卫使用
export {sources, post, get}

1.axios cancel token API
2.存入需要取消的请求列表导出给导航守卫使用
3.路由发生变化的时候取消当前页面还没有返回结果的请求,在复杂的页面中请求可能会有很多个,增加取消请求的功能可以让页面切换的时候不卡顿。
/src/router.js

...
import { sources } from '../service/request'
...
router.beforeEach((to, from, next) => {document.title = to.meta.title || to.name//路由发生变化时取消当前页面网络请求Object.keys(sources).forEach(item => {sources[item]('取消前页面请求')})for (var key in sources) {delete sources[key]}next()
})

request.js完整代码:

// 引入网络请求库 https://github.com/axios/axiosimport axios from 'axios'
import store from '../store'
import router from '../router'// 请求列表
const requestList = []
// 取消列表
const CancelToken = axios.CancelToken
let sources = {}// axios.defaults.timeout = 10000
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'axios.defaults.baseURL = process.env.BASE_URLaxios.interceptors.request.use((config) => {const request = JSON.stringify(config.url) + JSON.stringify(config.data)config.cancelToken = new CancelToken((cancel) => {sources[request] = cancel})if(requestList.includes(request)){sources[request]('取消重复请求')}else{requestList.push(request)store.dispatch('changeGlobalState', {loading: true})}const token = store.getters.userInfo.tokenif (token) {config.headers.token = token}return config
}, function (error) {return Promise.reject(error)
})axios.interceptors.response.use(function (response) {const request = JSON.stringify(response.config.url) + JSON.stringify(response.config.data)requestList.splice(requestList.findIndex(item => item === request), 1)if (requestList.length === 0) {store.dispatch('changeGlobalState', {loading: false})}if (response.data.code === 900401) {window.ELEMENT.Message.error('认证失效,请重新登录!', 1000)router.push('/login')}return response
}, function (error) {if (axios.isCancel(error)) {requestList.length = 0store.dispatch('changeGlobalState', {loading: false})throw new axios.Cancel('cancel request')} else {window.ELEMENT.Message.error('网络请求失败', 1000)}return Promise.reject(error)
})const request = function (url, params, config, method) {return new Promise((resolve, reject) => {axios[method](url, params, Object.assign({}, config)).then(response => {resolve(response.data)}, err => {if (err.Cancel) {console.log(err)} else {reject(err)}}).catch(err => {reject(err)})})
}const post = (url, params, config = {}) => {return request(url, params, config, 'post')
}const get = (url, params, config = {}) => {return request(url, params, config, 'get')
}export {sources, post, get}

以上。

axios基于常见业务场景的二次封装相关推荐

  1. GSF基于PHP Swoole Framework进行二次封装

    基于Swoole框架的封装扩展和完善,Swoole由于其文档太少,难度对于PHP程序员来说过于大,很多php程序员敬而远之. 工作之余基于Swoole frame 进行了二次封装,不断完善中 暂时定名 ...

  2. java二次封装_基于OKhttp+Rxjava2+Retrofit进行二次封装

    概述 基于Retrofit进行二次封装,优雅的初始化设置.基于Okhttp拦截器和基础缓存,封装了无网络和其他所有场景的缓存策略支持,以及频繁调用请求的丢弃策略. 特性 1.基于Retrofit的二次 ...

  3. WebView独立进程方案-基于腾讯X5的二次封装

    文章目录 更新记录 2021-12-06 2021-10-20 前言概述 基本使用 架构流程 命令模式 预初始化 前端使用文档与代码 参考 更新记录 2021-12-06 WebView支持多进程多任 ...

  4. java代码请求2次_Android基于OkHttpUtils网络请求的二次封装

    OkHttpUtils网络请求为什么进行二次封装? 1.减少代码量 2.后期换网络处理框架方便 二次封装的实现原理 1.将网络请求提取在一个方法中 2.对里面的可变参数,可以通过参数传递过去,也可以提 ...

  5. 前端VUE及PHP常见业务场景概括小结(程序猿提薪必备!!!)

    1.什么是IOC IOC是Inversion of Control的缩写,多数书籍翻译成"控制反转". 1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中 ...

  6. 基于elementui的input的二次封装(非常实用)

    基于本公司的需求进行封装 页面上很多input表单输入框,封装会使代码变得更加简洁 在每个组件里看的清晰明了 非常实用 全是精华 重点

  7. 选型最佳实践|从业务场景分析直播SDK

    摘要 近两年即时通讯/直播产品炙手可热,市场上针对ToB的产品日益增多,企业该如何去选型呢?本文分享了笔者对于直播产品的思考,将从直播SDK实例功能特性.常见业务场景.注意事项及最佳实践等方面介绍如何 ...

  8. 基于Istio的高级流量管理二(Envoy流量劫持、Istio架构、高级流量管理)

    文章目录 一.Envoy流量劫持机制(Iptables规则流转) 1.流量出向劫持流程 (1)envoy怎样劫持入向流量? (2)Envoy劫持到流量之后,干什么?(查询目的地) (3)获取目的地址之 ...

  9. 报表人的福音!25个实用报表模板合集,适用多个业务场景

    数据人总少不了和报表打交道,报表对企业生产经营的非常重要,通过对数据的监控.分析,挖掘出业务现象背后的逻辑,从而指导业务决策和运营. 随着企业的壮大,报表需求越来越多,每次业务需求都很紧急,表哥表姐们 ...

  10. Vue二次封装axios为插件使用

    照例先贴上 axios 的 gitHub 地址 不管用什么方式获取数据,对于一个项目来说,代码一定要利于维护其次是一定要写的优美,因此加上一层封装是必要的 vuejs2.0 已经不再维护 vue-re ...

最新文章

  1. Hyper-V应用指南之6-差异磁盘的使用[转]
  2. resamplingEnabled属性
  3. 无工具arp病毒检测
  4. docker ip地址_理解 Docker 网络(番外) -- 《Docker 源码分析》勘误
  5. springboot+sockjs进行消息推送(群发)
  6. 因为缺少xs-security.json文件导致的部署错误
  7. python合并多个pdf_python合并多个pdf文件
  8. EditPlus构建轻量级编译环境
  9. 嵌入式Linux系统编程学习之二十一命名管道(FIFO)
  10. Codeforces Round #372 (Div. 1) B. Complete The Graph
  11. 数据结构和算法9——哈希表
  12. 数字图像处理的起源与应用
  13. 迈信ep100交流伺服 含原理图、PCB图、C源代码等生产资 料。
  14. CCSP(Certified Cloud Security Professional) 国际注册云安全专家
  15. 使用Python实现消息轰炸
  16. 春节假期 最强抢票攻略
  17. python qq群发消息_使用python发送QQ消息,QQ消息自动发送
  18. 网页中怎样引导用户关注微信公众号
  19. SET TIMING ON
  20. matlab ssd检测,基于SSD神经网络的违章停车车辆实时检测方法与流程

热门文章

  1. (转)60s快速分析Linux性能
  2. HttpClient读取数据乱码的解决方案
  3. [置顶]灰のNOIP总结
  4. CSS3 基础(1)——选择器详解
  5. 存管 托管 监管 区别
  6. (原创)c#学习笔记03--变量和表达式03--变量04--变量的声明和赋值
  7. 在Qsys中创建用户自定义IP
  8. 删除Mysql数据表中多余的重复记录的sql语句
  9. 《学习之道》第十七章保持平静
  10. Delphi的命令行编译命令