axios取消多次请求,加锁

场景: 主要是微信公众号鉴权页面多个并发接口,发现401异常,就去微信换code,重定向回来,页面还会多次请求,需要取消这几次请求,然后全局拦截,请求一次去服务器后端去微信登录,换取openid,查询用户信息。

下面的是模拟接口,包括前端和后端

  • axios.js
'use strict'

import Vue from 'vue'
import axios from 'axios'
import source from '../utils/source'

let config = {
  timeout: 60 * 1000, // Timeout
}

const _axios = axios.create(config)
const logHttp = axios.create(config)

let lock = false

logHttp.interceptors.response.use(
  (response) => {
    lock = false
    return response
  },
  (error) => {
    lock = false
    return Promise.reject(error)
  }
)

_axios.interceptors.request.use(
  async (config) => {
    if (location.href.includes('code') && !lock) {
      lock = true
      await logHttp.get('/logApi', {
        params: {
          msg: 'okokokok',
          config,
        }
      })
      source.cancel()
    }

    if (lock) {
      source.cancel()
    }

    return config
  },
  function(error) {
    // Do something with request error
    return Promise.reject(error)
  }
)

// Add a response interceptor
_axios.interceptors.response.use(
  function(response) {
    // Do something with response data
    return response
  },
  function(error) {
    // Do something with response error
    return Promise.reject(error)
  }
)

Plugin.install = function(Vue) {
  Vue.axios = _axios
  window.axios = _axios
  Object.defineProperties(Vue.prototype, {
    axios: {
      get() {
        return _axios
      },
    },
    $axios: {
      get() {
        return _axios
      },
    },
  })
}

Vue.use(Plugin)

export default Plugin

  • utils/source.js
import axios from 'axios'

const source = axios.CancelToken.source()
export default source

  • App.vue (模拟页面)
<script>
import source from './utils/source'

export default {
  name: 'App',
  
  created() {
    this.$axios.get('/ping', {
      params: {
        name: 'xiaoming'
      },
      cancelToken: source.token
    })

    this.$axios.get('/ping', {
      params: {
        name: 'xiaoming22222'
      },
      cancelToken: source.token
    })

    this.$axios.get('/ping', {
      params: {
        name: 'xiaoming3333'
      },
      cancelToken: source.token
    })
  }
}
</script>
  • 后台nodejs server.js
const app = require('express')()

app.get('/logApi', (req, res) => {
  console.log('logApi',req.query, Date.now());
  res.send('ok')
})

app.get('/ping', (req, res) => {
  console.log('ping', req.query, Date.now());
  res.send('pong')
})

app.listen(9090, () => {
  console.log(`server is running at PORT 9090 ...`);
})

你可能感兴趣的:(axios)