vue项目中 axios请求拦截器与取消pending请求功能 - 年少、 - 博客园
在開(kāi)發(fā)vue項(xiàng)目中,請(qǐng)求是不可缺少的,在發(fā)送請(qǐng)求時(shí)常常需要統(tǒng)一處理一些請(qǐng)求頭參數(shù)等設(shè)置與響應(yīng)事件,這時(shí)利用請(qǐng)求攔截器再好不過(guò)。
這里以axios請(qǐng)求為例
實(shí)現(xiàn)了設(shè)置統(tǒng)一請(qǐng)求頭添加token, 其中token在登錄時(shí)被存入了localStorage中。
同時(shí)攔截器利用new cancelToken與定義的cancelPending方法實(shí)現(xiàn)了可以取消正在pending狀態(tài)的請(qǐng)求,什么情況會(huì)需要取消請(qǐng)求呢?
如下兩種情況:
1.?有一個(gè)局部分頁(yè)時(shí),用戶快速點(diǎn)擊第2頁(yè),然后繼續(xù)點(diǎn)擊第3頁(yè),如果網(wǎng)絡(luò)不太穩(wěn)定時(shí),第2頁(yè)的請(qǐng)求正在發(fā)送中,還未響應(yīng),但第3頁(yè)的請(qǐng)求先響應(yīng)了,過(guò)了一會(huì)第2?頁(yè)請(qǐng)求才響應(yīng),這時(shí)用戶處于第3頁(yè),但看到的數(shù)據(jù)確是第2頁(yè)的,當(dāng)然有人會(huì)說(shuō)可以在發(fā)送請(qǐng)求過(guò)程中禁用掉分頁(yè)按鈕點(diǎn)擊,但我感覺(jué)體驗(yàn)不太好,為何禁用呢,直接點(diǎn)擊第3頁(yè)時(shí)中斷掉之前相同的請(qǐng)求即可。
2.?切換路由時(shí),上一路由頁(yè)面中仍有未響應(yīng)的請(qǐng)求時(shí)切換了路由,應(yīng)該把正在pending的所有請(qǐng)求中斷取消掉。
?
下面是完整實(shí)現(xiàn)axios請(qǐng)求攔截器與取消pending請(qǐng)求功能的代碼
let pending = []; let cancelToken = axios.CancelToken; let cancelPending = (config) => { pending.forEach((item, index) => { if(!!config){ if(item.u == config.url){ item.f(); //取消請(qǐng)求 pending.splice(index, 1); //移除當(dāng)前請(qǐng)求記錄 }; }else{ item.f(); //取消請(qǐng)求 pending.splice(index, 1); //移除當(dāng)前請(qǐng)求記錄 } }); };//驗(yàn)證登錄狀態(tài) router.beforeEach((to, from, next) => { //如果是需要驗(yàn)證登錄狀態(tài)的頁(yè)面 if(to.matched.some(record => record.meta.requireAuth)){ let token = localStorage.getItem('token'); //如果已經(jīng)登錄,則正常進(jìn)入 if(!!token){ cancelPending(); next(); }else{ next({'name': 'login', 'query': {'redirect': to.fullPath}}); }; }else if(to.name == 'login'){ //如果是登錄頁(yè),則驗(yàn)證如果當(dāng)前是登錄狀態(tài)自動(dòng)跳轉(zhuǎn)至系統(tǒng)主頁(yè),否則正常進(jìn)入登錄頁(yè) let token = localStorage.getItem('token'); //如果已經(jīng)登錄,則重定向至系統(tǒng)首頁(yè) if(!!token){ router.push({'name': 'SystemWelcome'}); }else{ next(); }; }else{ //其他頁(yè)面正常進(jìn)入 next(); }; });//axios 請(qǐng)求攔截器 axios.interceptors.request.use(config => { let token = localStorage.getItem('token'); if (!!token) { // 判斷是否存在token,如果存在的話,則每個(gè)http header都加上token config.headers.Authorization = `token ${token}`; }; cancelPending(config); config.cancelToken = new cancelToken((c) => { pending.push({'u': config.url, 'f': c}); }); return config; }, err => { return Promise.reject(err); }); //響應(yīng)攔截器 axios.interceptors.response.use(response => { cancelPending(response.config); return response; }, error => { if (error.response) { switch (error.response.status) { case 401: // 返回 401 清除token信息并跳轉(zhuǎn)到登錄頁(yè)面 localStorage.removeItem('token'); router.push({'name': 'login', 'query': {'redirect': router.currentRoute.fullPath}}); } } return {data: {}}; // 返回接口返回的錯(cuò)誤信息(這里返回空對(duì)象是為了避免控制臺(tái)報(bào)錯(cuò)) });總結(jié)
以上是生活随笔為你收集整理的vue项目中 axios请求拦截器与取消pending请求功能 - 年少、 - 博客园的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SqlServerSQL语句方式--视图
- 下一篇: vue项目如何打包扔向服务器 - Hi-