1、vue项目,在main.js中设置了vue-resource的全局拦截器;某一页面采用定时器实现长连接,项目需求是获取当前页面的请求,在离开页面时将请求清除;因为要将请求存储到stroe中,所以需要在拦截器中使用对应组件的this,但使用时却发现,获取到的this并不是对应的组件实例;最终采用了在VUE的原型上定义函数,并在拦截器中调用该函数,这样就能正确获取到this,实现方式如下

let vm = new Vue({
  router,
  store,
  i18n,
  render: h => h(App)
}).$mount('#app');


Vue.prototype.pushRequest = function (request) {
 // console.log(this);此处this为请求所在页面的Vue实例
  this.$store.commit('updateRequest',request);
};
Vue.http.interceptors.push((request, next) => {
  //console.log(this)//此处this获取不到请求所在页面的Vue实例
  if(request.url === 'api/v2.0/monitor/data'){
    vm.pushRequest(request);
  }
 let timeout ;
 if(request._timeout){
   timeout = setTimeout(()=>{
     if(request.onTimeout){
       request.onTimeout(request);
       request.abort();
     }
   },request._timeout);
 }
  next((response) => {
   clearTimeout(timeout);
    return response;
  });
});

ps:尝试过在对应的组件里设置请求拦截器,本来想设置‘局部拦截器’,在‘局部拦截器’中获取能获取到当前组件的this,后发现这样会导致组件实例一直存在:每进入一次该页面,就会生成一个新的组件实例,并且旧的实例不会被清除,而且两个组件都会发出同样的请求;猜测可能拦截器只能设置全局拦截器,所谓的‘局部拦截器’是不行的,遂放弃

2、上面的代码中,除了对特定请求做拦截处理外,还有一个对请求超时做处理的功能;页面长连接服务器端设置的超时时间为3分钟,但是在chrome浏览器中发现,请求超时未两分钟时浏览器就会报错,因此加上自定义的超时处理,设置超时时间,到点清除该请求,进入下一次请求,如上设置后,需要在请求发起处设置超时时间和超时处理函数:

 context.$http.post('api/v2.0/monitor/data',info,{_timeout:118000,onTimeout:(request)=>{console.log('超时')},
  }).then(function (res) {
     
      },function(err){
        if(context.$route.path==='/monitor'){
          context.timeout1 = setTimeout(that._getMonData1(context,info),5000);
        }else{
          context.timeout1 ='';
        }
      })
做超时处理后,当前请求停止,执行 err函数,判断是否在长连接页面,是则发出下一次请求;


Logo

前往低代码交流专区

更多推荐