Vue+Axios:使用攔截器來取消多次重複的請求
阿新 • • 發佈:2021-01-07
這篇部落格主要解決問題1,即攔截相同url的axios請求,網上教程是一堆,但好像大家都是從同一份魔改出來的?因此我頭皮發麻的想了好久,在思否的提問只有21個瀏覽...
推薦閱讀Axios的中文文件
首先需要明白攔截器的工作原理,axios中內建了兩個攔截器,請求攔截器與響應攔截器,分別通過以下兩個方法呼叫
axios.interceptors.request.use()
axios.interceptors.response.use()
攔截器的觸發:
對於單個請求來說,在請求傳送後會觸發request攔截器進行攔截。
因此可以有以下思路,建立一個空陣列,第一次請求成功傳送後將本次請求的url儲存起來,下一次再次傳送請求,會先在請求攔截器中檢驗這一請求的url是否在這個陣列中被儲存了,
如果是,則取消本次請求(AXIOS提供了cancelToken來取消請求,詳見後文)。
如果有需要的話,在響應攔截器中,在成功返回響應後將本次請求的url從陣列中去掉,以便後續的使用,這一情況適用於防止使用者多次點擊發送重複請求?即這個介面後面還有可能用
let pending = []; //宣告一個數組用於儲存每個請求的取消函式和axios標識 let cancelToken = axios.CancelToken; let removePending = (config) => { // console.log(config); for(let i in pending){ if(pending[i].url === axios.defaults.baseURL+config.url) { //在當前請求在陣列中存在時執行取消函式 pending[i].f(); //執行取消操作 //pending.splice(i, 1); 根據具體情況決定是否在這裡就把pending去掉 console.log(pending[i].url); } } }
請求攔截器與響應攔截器:
axios.interceptors.request.use(config => { removePending(config); //在一個axios傳送前執行一下判定操作,在removePending中執行取消操作 // console.log(config.url); config.cancelToken = new cancelToken(function executor(c){//本次axios請求的配置新增cancelToken pending.push({ // url: config.url, url: axios.defaults.baseURL+config.url, f:c }); // console.log(axios.defaults.baseURL+config.url); //將本次的url新增到pending中,因此對於某個url第一次發起的請求不會被取消,因為還沒有配置取消函式 }); return Promise.resolve(config); }, error => { return Promise.reject(error) }) axios.interceptors.response.use(data => { // removePending(data.config); //在一個axios響應後再執行一下取消操作,把已經完成的請求從pending中移除 // console.log(data.config);//如果返回undefined說明被攔截了 return Promise.resolve(data) }, error => { //載入失敗 return {'data':{}} })
這裡的詳解見上面的axios中文文件哈,如果懶得看只要知道這裡的c是new cancelToken構造器生成的取消函式就行。
注意這裡兩行不同的url,使用上面一行會導致無法攔截,因為專案前面手動設定了axios.defaults.baseURL,導致這裡傳入的url如果不加上baseURL,就只會是/topic?lastCursor=xxxxxx&pageSize=20,
但在pending陣列⬇中的則是完整的url,就會導致url不匹配從而無法攔截。
建議把這裡註釋掉的控制檯列印程式碼好好執行幾遍~