123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- import qs from 'qs'
- import VerifyPoints from './verify-popup'
- const verify = new VerifyPoints()
- const JSONOrFormData = config => {
- let type = ''
- const contentType = config.headers['Content-Type']
- // json --- application/json;charset=utf-8
- // formData --- application/x-www-form-urlencoded
- const contentTypeMap = {
- json: 'application/json',
- formData: 'application/x-www-form-urlencoded'
- }
- if (!contentType) return 'json'
- for (const key in contentTypeMap) {
- const matching = contentType.includes(contentTypeMap[key])
- if (matching) {
- type = key
- break
- }
- }
- return type
- }
- // 缓存原有拦截器
- let cacheResponseInterceptors = []
- // 缓存所有拦截器,并清除实例上所有拦截器,
- function clearAllResponseInterceptors (service) {
- // https://github.com/axios/axios/blob/v1.x/lib/core/InterceptorManager.js
- // 移除所有拦截器,github中的这个clear函数后来被移除了
- const handlers = service.interceptors.response.handlers
- if (Array.isArray(handlers) && handlers.length > 0) {
- for (let i = 0; i < handlers.length; i++) {
- cacheResponseInterceptors.push(handlers[i])
- }
- service.interceptors.response.handlers = []
- }
- }
- // 从缓存恢复拦截器
- function restoreResponseInterceptors (service) {
- if (Array.isArray(cacheResponseInterceptors) && cacheResponseInterceptors.length > 0) {
- service.interceptors.response.handlers = cacheResponseInterceptors
- // 恢复完成后及时清除缓存数组
- cacheResponseInterceptors = []
- }
- }
- // 清除所有拦截器,并注册当前拦截器
- // 移除拦截器后必须在某处恢复,否则会影响其他请求
- function clearOtherResponseInterceptors (service) {
- clearAllResponseInterceptors(service)
- registerInterceptors(service)
- }
- function closeVerify () {
- if (verify.show) {
- verify.verify({ value: false })
- }
- }
- export default function registerInterceptors (service) {
- // 注册响应拦截器
- service.interceptors.response.use(async (response) => {
- const res = response.data
- const config = response.config
- // 如果请求不是200,有可能是403(被拉黑了),就直接跳过本次拦截
- if (response.status !== 200) {
- // 如果全局验证码显示,并且返回结果正常。则关闭验证码
- closeVerify()
- return response
- }
-
- // 验证码验证成功
- if (res.antiVerify === 1) {
- /**
- * 思路1(正在使用):移除其他响应拦截器,获取到response并返回后,在恢复拦截器
- * 优点:能够完全还原新请求的信息(包含响应头等,兼容验证请求响应头和正常请求响应头不同的情况)
- * 缺点:实现稍微复杂
- *
- * 思路2:仅替换response中请求返回的数据。不操作任何拦截器,await service(conf)后,直接替换response中的data即可
- * 优点:实现简单
- * 缺点:不能实现<思路1>中完全复现响应头的情况
- */
- // 移除其他响应拦截器
- clearOtherResponseInterceptors(service)
- let r = response
- try {
- r = await service(config)
- // 恢复响应拦截
- restoreResponseInterceptors(service)
- } catch (error) {
- // 恢复响应拦截
- restoreResponseInterceptors(service)
- console.error(error)
- } finally {
- closeVerify()
- }
- return r
- } else {
- restoreResponseInterceptors(service)
- }
- // 需要验证
- if (res.antiVerify === -1 && res.textVerify) {
- // 等待验证码操作完成
- const iReceivedMsg = await new Promise((resolve) => {
- verify.verify({
- value: true,
- imgBase64: res.imgData,
- textVerify: res.textVerify,
- refresh () {
- resolve({
- type: 'refresh'
- })
- },
- confirm (msg) {
- resolve({
- type: 'confirm',
- imgw: msg.imgWidth,
- antiVerifyCheck: msg.pointsCoordinate.join(';')
- })
- }
- })
- })
- // 如果确定事件触发
- if (iReceivedMsg && iReceivedMsg.type === 'confirm') {
- // GET请求在data中添加数据, POST请求在params中添加数据
- const requestType = config.method.toUpperCase()
- switch (requestType) {
- case 'GET': {
- if (config.params) {
- config.params.imgw = iReceivedMsg.imgw
- config.params.antiVerifyCheck = iReceivedMsg.antiVerifyCheck
- } else {
- config.params = iReceivedMsg
- }
- break
- }
- case 'POST': {
- // 判断json还是formData
- const sendVerify = {
- imgw: iReceivedMsg.imgw,
- antiVerifyCheck: iReceivedMsg.antiVerifyCheck
- }
- const sendType = JSONOrFormData(config)
- if (sendType === 'formData') {
- if (config.data) {
- // 先把字符串转为对象,赋值后在转回字符串
- const cacheMsg = qs.parse(config.data)
- config.data = qs.stringify({
- ...cacheMsg,
- ...sendVerify
- })
- } else {
- config.data = qs.stringify(sendVerify)
- }
- } else if (sendType === 'json') {
- if (config.data) {
- // 先把字符串转为对象,赋值后在转回字符串
- config.data = JSON.parse(config.data)
- Object.assign(config.data, sendVerify)
- config.data = JSON.stringify(config.data)
- } else {
- config.data = JSON.stringify(sendVerify)
- }
- }
- break
- }
- default: {
- console.log('非常规请求,请单独配置拦截请求内容,并写入参数 --- 来自: @jianyu/vue-anti')
- break
- }
- }
- }
- // 重发请求以验证《验证码》是否正确
- // 此时不需要当前拦截器以外的拦截器
- // 移除其他响应拦截器,在请求时恢复
- clearOtherResponseInterceptors(service)
- return service(config)
- } else {
- return response
- }
- }, error => {
- return error
- })
- }
|