从axois拦截器控制微调器显示/隐藏时请求太多

时间:2018-01-21 14:09:18

标签: vue.js axios

我有一个用Vue编写的SPA(Webpack),我希望根据应用程序当前是否正在处理HTTP请求或响应来控制微调器的可见性。

在一些教程之后,我想出了事件总线方案并做到了这一点:

创建eventBus.js

import Vue from 'vue';
export const eventBus = new Vue();

我在created()的{​​{1}}挂钩中设置我的axios拦截器。以下是该组件中必要功能的含义:

App.vue

请忽略一些与问题无关的代码,但我想说明事情是如何设置的。问题是,一旦我访问我的主页,应用程序就会一遍又一遍地进行启动GET请求,直到我的服务器返回429错误。

有趣的是,在我的data() { return { showLoader: false }; }, created(){ this.setAxiosInterceptors(); // some code removed // } }, mounted() { eventBus.$on('show-loader', () => { this.showLoader = true; }); eventBus.$on('hide-loader', () => { this.showLoader = false; }); }, methods: { setAxiosInterceptors() { var tokenCookieName = this.$store.getters.getCookieNames.apiToken; var cookieDefaultValue = this.$store.getters.getCookieDefaultValue; // token expired middleware this.axios.interceptors.response.use(response => { var data = response.data; if(data.info.api_token) { this.$cookie.set(tokenCookieName, data.info.api_token); } if(data.status == 'error' && data.info.login_failed) { this.$cookie.set(tokenCookieName, cookieDefaultValue); window.location = '/'; // not possible to use Vue router here } eventBus.$emit('hide-loader'); return response; }, error => { eventBus.$emit('hide-loader'); console.log('Response interception failed!'); return Promise.reject(error); }); // attach API token middleware this.axios.interceptors.request.use(config => { var apiToken = this.$cookie.get(tokenCookieName); if (!apiToken) { apiToken = cookieDefaultValue; } config.headers.Authorization = 'Bearer ' + apiToken; eventBus.$emit('show-loader'); return config; }, error => { eventBus.$emit('hide-loader'); console.log('Request interception failed!'); return Promise.reject(error); } ); } } 处理程序中,如果我只执行eventBus.$on,则此行为不会出现(当然,微调器也不起作用)但是只要我更改变量或调用vuex动作,就会开始无限重新加载

有任何线索吗?

1 个答案:

答案 0 :(得分:0)

main.js文件中

Vue.prototype.$axios = axios.create(
  {
    headers:
      {
        'Content-Type': 'application/json',
      },
    baseURL: process.env.API_URL
  }
);

Vue.prototype.$axios.interceptors.request.use(
  config =>
  {
    eventBus.$emit('show_spin');
    let token = getTokenID();
    if(token && token.length) config.headers['Authorization'] = token;
    return config;
  },
  error =>
  {
    eventBus.$emit('hide_spin');
    if (error.status === 401) VueRouter.push('/login');
    else throw error;
  }
);
Vue.prototype.$axios.interceptors.response.use(
  response =>
  {
    eventBus.$emit('hide_spin');
    return response;
  },
  error =>
  {
    eventBus.$emit('hide_spin');
    return new Promise(function(resolve,reject)
    {
      if (error.config && error.response && error.response.status === 401 && !error.config.__isRetry)
      {
        myVue.refreshToken(function()
        {
          error.config.__isRetry = true;
          error.config.headers['Authorization'] = getTokenID();
          myVue.$axios(error.config).then(resolve,reject);
        },function(flag) // true = invalid session, false = something else
        {
          if(process.env.NODE_ENV === 'development') console.log('Could not refresh token');
          if(getUserID()) myVue.showFailed('Could not refresh the Authorization Token');
          reject(flag);
        });
      }
      else throw error;
    });
  }
);

let myVue = new Vue(
{
  el: '#app',
  data: function()
  {
    return {
      spin_visible: 0, // dynamically show/hide spinner
    };
  },
  created: function()
  {
    eventBus.$on('show_spin', this.showSpin);
    eventBus.$on('hide_spin', this.hideSpin);
  },
  methods:
  {
    showSpin: function()
    {
      this.spin_visible++;
    },
    hideSpin: function()
    {
      if(this.spin_visible>0) this.spin_visible--;
    }, 
    ....

,然后在App.vue

<template>
  <router-view/>
  <div class="spinner" v-show="$root.spin_visible"> 
  <!-- define your spinner here -->
  </div>
</template>