版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/github_39532240/article/details/78651185
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函數,判斷是否在長連接頁面,是則發出下一次請求;