vue+axois 封裝請求+攔截器(請求鎖+統一處理錯誤碼)


 需求

  1.  封裝常用請求
  2.  攔截器-請求鎖
  3.  統一處理錯誤碼

 

一、封裝常用的請求

  解決痛點:不要每一個模塊的api都還要寫get,post,patch請求方法。直接將這些常用的方法封裝好。

  解決方案:寫一個類,封裝好常用的請求

  部分源碼如下

export default class PublicAPI {
    constructor(url) {
        this.url = url; } get(params, filter) { if (Array.isArray(params)) { filter = typeof filter === 'object' ? JSON.stringify(filter) : filter; let qs = filter ? '?filter=' + filter : ''; return axios.get(this.url + '/' + params.join('/') + qs); } params = params || {}; return axios.get(this.url, { params }); } delete(id) { return axios.delete(`${this.url}/${id}`);  } post(params) { return axios.post(this.url, params); }
   //常用請求 都可以封裝在這里 }

 

二、攔截器-請求鎖

  解決痛點:限制同一時間發多個同一個請求

  解決方案:利用axios的攔截器 + axios.CancelToken,限制同一個請求多次發送

  源碼如下

方案一:簡單款

let pending = []; //聲明一個數組用於存儲每個ajax請求的取消函數和ajax標識
let CancelToken = axios.CancelToken;
let removePending = (config) => { for(let p in pending){ if(pending[p].u === config.url + '&' + config.method) { //當前請求在數組中存在時執行函數體 pending[p].f(); //執行取消操作 pending.splice(p, 1); //把這條記錄從數組中移除  } } }

方案二:復雜款(這個是在掘金上看到的,原鏈接找不到了)

let pending = {};
/**
 * cancelKey管理器
 *
 * @return {Object} 返回一個對象,對象暴露兩個方法,一個可以獲取本次請求的key,一個是設置本次請求的key
 * @memberof HttpRequest
 */ let cancelKeyManager = () => { const expose = {}; expose.setKey = function setKey(config) { const { method, url, params, data } = config; expose.key = `${method}|${url}`; //expose.key = method === 'get' ? `${expose.key}&${JSON.stringify(params)}` : `${expose.key}&${JSON.stringify(data||{})}`;  }; expose.getKey = function getKey() { return expose.key; }; return expose; }; /** *處理請求攔截和請求取消 * * @param {object} config axios配置對象 * @param {boolean} [isCancel=true] 標識是請求取消還是攔截請求 * @return {object} 返回axios配置對象 * @memberof HttpRequest */ let handleRequestCancel = (config, isCancel = false) => { // 設置本次請求的key const { setKey, getKey } = cancelKeyManager(); setKey(config); const key = getKey(); const CancelToken = axios.CancelToken; // 取消已經發出去的請求 if (isCancel) { removeRequest(key, true); // 設置本次請求的cancelToken config.cancelToken = new CancelToken(c => { pending[key] = c; }); } else { // 攔截本次請求 config.cancelToken = new CancelToken(c => { // 將本次的cancel函數傳進去 pending[key] = c; removeRequest(key, true, c); }); } return config; }; /** * 移除請求 * * @param {string} key 標識請求的key * @param {boolean} [isRequest=false] 標識當前函數在請求攔截器調用還是響應攔截器調用 * @param {function} c cancel函數 * @memberof HttpRequest */ let removeRequest = (key, isRequest = false, c) =>{ // 請求前先判斷當前請求是否在pending中,如果存在有兩種情況: // 1. 上次請求還未響應,本次的請求被判為重復請求,則調用cancel方法攔截本次重復請求或者取消上一個請求 // 2. 上次請求已經響應,在response中被調用,清除key  console.log(key,pending); if (pending[key]) { if (isRequest) { Message.error({ message: '請求過於頻繁' }); } else { // 上一次請求在成功響應后調用cancel函數刪除key delete pending[key]; } } };

 

三、統一處理錯誤碼

  解決痛點:每個請求都需要處理錯誤信息,特別是一些常用的錯誤(堅持能封裝就封裝的思想),當然具體業務處理邏輯這是各自處理啦!

  解決方案:用axios攔截器,將返回來的錯誤統一處理,最常用的就是401 token失效吧!一般是要前后端統一錯誤碼的,固定的錯誤碼做固定的事情!

  部分源碼如下(感覺只適合部分)

axios.interceptors.response.use(
response => {
return new Promise((resolve, reject) => { //很重要 用promise 接收自定義錯誤碼
let data = response.data;
if (data.code === 'ok') {
return resolve({
data: data.data || data || {},
response: response
});
} else {
switch (data.code) {
case '10500': //自定義code
reject({
response: {
code: '10500',
status: 500,
msg: data.msg
}
});
break;
default:
reject(response);
}
}
});
},error => {}
)

 

總結

  給出的源碼比較分散,僅提供思路。

  在項目中這么一套全家桶用下來,十分巴適~~~

  有疑問可以給我留言,我會盡力解答哦


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM