Vue:Axios前端拦截器
需求描述
????限制用戶多次點擊按鈕,頻繁地發送同一個請求,影響頁面渲染效果,降低前端的無效接口請求操作(其中涉及到Map、Array、Promise的一些基本操作)。
解決方案
????由于所接觸的是Vue項目,項目中使用的接口請求工具為axios(點擊此處,查看官網),因此,采用編寫前端攔截器的方式來對除第一次之外的——多個處于pending等待狀態的同一個無效請求進行過濾,即:只有首次發送的請求會被正常處理,后續的會被直接過濾掉。
基本思路
????使用一個Map集合對象,保存用戶發送的每個請求。Map中每一個元素的requestKey唯一標識值由請求的method、url和data參數構成。
????axios攔截器分別為:請求攔截器和響應攔截器,其中,
????????①請求攔截器:在進行接口數據請求時,判斷是否已經有相同的請求在執行(Map集合中是否存在由requestKey標識的請求對象),如果有,就直接取消掉當前一次請求;如果沒有,則正常執行。
????????②響應攔截器:在正常執行完畢一次接口請求時,就再次獲取該請求的requestKey標識值,并根據requestKey標識值從Map集合中移除,以確保下一次接口請求的正常執行。
代碼編寫
核心代碼
//記錄處理pending狀態的Axios請求對象var pendingRequestMap = new Map();//攔截器配置//1-請求攔截器配置axios.interceptors.request.use(function (config) {console.warn("請求攔截器...");//校驗-method|url|datalet requestKey = `${config.method}-${config.url}-${config.data}`;//創建request請求keylet cancelFunction = undefined;config.requestKey = requestKey;//掛載requestKey到config對象上//獲取axios取消請求回調函數config.cancelToken = new axios.CancelToken((cancel)=>{cancelFunction = cancel;});//創建cancelTokenconsole.log(config);//判斷當前pendingRequestMap中是否存在當前requestKeyif(pendingRequestMap.has(requestKey)){//執行請求攔截-取消當前一次的請求cancelFunction();}else {//保存當前一次的請求pendingRequestMap.set(requestKey,config);}return Promise.resolve(config);//改變config狀態為resolved},function (error) {return Promise.reject(error);});//2-響應攔截器配置axios.interceptors.response.use(function (response) {console.warn("響應攔截器...");let requestKey = response.config.requestKey ;//獲取當前請求的Key值//如果執行成功-根據key值,從pendingRequestMap中移除當前請求configpendingRequestMap.delete(requestKey);return Promise.resolve(response);//改變響應結果狀態為resolved},function (error) {return Promise.reject(error);//改變響應結果狀態為rejected});完整代碼
????以示例demo的形式給出。
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>AxiosTest</title><script src="./axios/axios.min.js"></script> </head> <body><button id="sendAjax">發送請求</button> </body> <script>//記錄處理pending狀態的Axios請求對象var pendingRequestMap = new Map();//攔截器配置//1-請求攔截器配置axios.interceptors.request.use(function (config) {console.warn("請求攔截器...");//校驗-method|url|datalet requestKey = `${config.method}-${config.url}-${config.data}`;//創建request請求keylet cancelFunction = undefined;config.requestKey = requestKey;//掛載requestKey到config對象上//獲取axios取消請求回調函數config.cancelToken = new axios.CancelToken((cancel)=>{cancelFunction = cancel;});//創建cancelTokenconsole.log(config);//判斷當前pendingRequestMap中是否存在當前requestKeyif(pendingRequestMap.has(requestKey)){//執行請求攔截-取消當前一次的請求cancelFunction();}else {//保存當前一次的請求pendingRequestMap.set(requestKey,config);}return Promise.resolve(config);//改變config狀態為resolved},function (error) {return Promise.reject(error);});//2-響應攔截器配置axios.interceptors.response.use(function (response) {console.warn("響應攔截器...");let requestKey = response.config.requestKey ;//獲取當前請求的Key值//如果執行成功-根據key值,從pendingRequestMap中移除當前請求configpendingRequestMap.delete(requestKey);return Promise.resolve(response);//改變響應結果狀態為resolved},function (error) {return Promise.reject(error);//改變響應結果狀態為rejected});//事件注冊-發送Axios請求var btn = document.getElementById("sendAjax");btn.addEventListener("click",function (ev) {axios({method: 'get',url: '/shqrpweb/QueryShort/loadChangzhu/test1',data: {code:"310101"}}).then(function (result) {console.log(result)});});</script> </html>案例翻轉
????上述代碼是對同一個接口的多次請求進行過濾,只保留第一次請求的實現。那么,如果指向保留最后一次請求,而取消掉前幾次的請求呢?示例代碼如下,
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>AxiosTest</title><script src="./axios/axios.min.js"></script> </head> <body><button id="sendAjax">發送請求</button> </body> <script>//攔截器配置//記錄已經發起的所有請求var requestPool = new Array();//1-請求攔截器配置axios.interceptors.request.use(function (config) {console.warn("請求攔截器...");//校驗-method|url|datalet requestKey = `${config.method}-${config.url}-${config.data}`;//創建request請求keyif(requestPool&&requestPool.length>0){//先判斷是否存在相同的請求requestPool.forEach((e,index)=>{if(e['key'] === requestKey){e['value'].cancel();//存在相同的請求-執行取消操作delete requestPool[index];//從請求池中移除對應的請求}});requestPool = requestPool.filter(item=>typeof item !== "undefined");//過濾掉空白元素}config.requestKey = requestKey; //掛載requestKey到config上//將取消請求的cancelToken掛載到config實例上console.log(config);config.cancelToken = new axios.CancelToken((cancel)=>{config.cancel = cancel;});//創建cancelToken//將當前請求添加到請求池中requestPool.push({key:requestKey,value:config,});//將當前config狀態轉換為resolvedreturn Promise.resolve(config);},function (error) {return Promise.reject(error);});//2-響應攔截器配置axios.interceptors.response.use(function (response) {console.warn("響應攔截器...");let requestKey = response.config.requestKey ;//獲取當前請求的Key值//如果執行成功-根據key值,從請求池requestPool中移除當前請求configrequestPool = requestPool.filter(item=>item['key']===requestKey);console.log(requestPool);return Promise.resolve(response);//改變響應結果狀態為resocancelTokelved},function (error) {return Promise.reject(error);//改變響應結果狀態為rejected});//事件注冊-發送Axios請求var btn = document.getElementById("sendAjax");btn.addEventListener("click",function (ev) {axios({method: 'get',url: '/shqrpweb/QueryShort/loadChangzhu/test1',data: {code:"310101"}}).then(function (result) {console.log(result)});}); </script> </html>總結
以上是生活随笔為你收集整理的Vue:Axios前端拦截器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电力工程设计一次回路—(330~500K
- 下一篇: 【数据结构与算法】栈的基本运算(出栈、入