axios請求二次封裝之避免重復發(fā)送請求
前言
Axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。
axios 是目前最優(yōu)秀的 HTTP 請求庫之一, 我們封裝 axios 請求也是為了讓代碼看的更加清晰, 后期好維護.
目的
- 實現(xiàn)請求攔截
- 實現(xiàn)響應攔截
- 常見錯誤處理
- 不能請求頭設置
- api 集中式管理
(取消重復請求,重復發(fā)送請求, 請求緩存等情況均還未實現(xiàn))
文件結(jié)構(gòu)

實現(xiàn)
index.js內(nèi)代碼如下:
引入
// 引入 axios import axios from 'axios'; // 請求配置單獨寫一個文件 baseurl.js import serverConfig from './baseurl.js'
創(chuàng)建一個實例
const serviceAxios = axios.creat({
baseURL: serverConfig.baseURL, //基礎請求地址
timeout: 1000 , //請求超時設置
withCredentials: false, // 跨域請求是否需要攜帶 cookie
})
請求攔截
serviceAxios.interceptors.request.use(
(config) => {
console.log("請求配置", config);
// 是否使用 Token,
if(serverConfig.useTokenAuthorization) {
config.headers["Authorization"] = localStorage.getItem("token");
}
// 設置請求頭
if(config.method === "post") {
config.headers["content-type"] = "application/x-ww-form-urlencoded";
// config.data = qs.stringify(config.data); //序列化 效果等同于下行代碼
config.requestType = "form"
} else {
config.headers["content-type"] = "application/json"
}
// 返回
return config
},
(error) => {
Promise.reject(error)
}
)
響應攔截
serviceAxios.interceptors.response.use(
(res) => {
console.log("響應攔截", res);
let data = res.data;
// 處理自己的業(yè)務邏輯,如 token 是否過期...
return data;
},
(error) => {
let message = ""
if(error && error.response) {
switch (error.response.status) {
case 302:
message = "接口重定向了! ";
break;
case 400:
message = "參數(shù)不正確! ";
break;
case 401:
message = "您未登錄, 或者登錄已經(jīng)超時, 請先登錄! "
break;
case 403:
message = "您還沒有權(quán)限操作! ";
break;
case 404:
message = `請求地址出錯: ${error.response.config.url}`;
break;
case 408:
message = "請求超時! ";
break;
case 409:
message = "系統(tǒng)已存在相同數(shù)據(jù)! "
break;
case 500:
message = "服務器內(nèi)部錯誤! "
break;
case 501:
message = "服務未實現(xiàn)! "
break;
case 502:
message = "回答錯誤! "
break;
case 503:
message = "服務不可用"
break;
case 504:
message = "服務暫時無法訪問, 請稍后再試"
break;
case 505:
message = "HTTP 版本不受支持! "
break;
default:
message = "異常問題, 請聯(lián)系管理員! "
break;
}
}
return Promise.reject(message);
}
);
取消重復發(fā)送請求
實現(xiàn)思想
唯一標識值 : 每次發(fā)起請求的時候根據(jù)請求的方式,請求URL,請求攜帶參數(shù)設置一個唯一標識值.
請求隊列: 創(chuàng)建一個map對象儲存請求的唯一標識值.
每次發(fā)送請求的時候, 在請求攔截中判斷請求隊列中是否存在這個請求, 存在就說明這個請求正在進行中,那么就取消正在發(fā)送的請求,重新發(fā)送請求; 不存在就將本次請求加入請求隊列中.
在響應攔截中將本次請求從請求隊列中移除.
??生成唯一標識值函數(shù)
import qs from 'qs'
function regsoleKey(config){
const {method, url, params, data } = config;
return [method, url, qs.stringify(params), qs.stringify(data)].join('&')
}
??將請求加入請求隊列函數(shù)
const reqQueue = new Map();
function addreqQueue(config){
//調(diào)用生成唯一標識值函數(shù), 生成 requestKey
const requestKey = regsoleKey(config);
//為每個請求創(chuàng)建一個專屬的 CancelToken(用于取消請求)
config.cancelToken = config.cancelToken || new axios.CancelToken((cancel)=>{
// 判斷 reqQueue 中是否含有 requestKey,
// 將 requestKey 與 CancelToken 以鍵值對的形式保存到map對象中
if(!reqQueue.has(requestKey)){
reqQueue.set(requestKey,cancel)
}
});
}
??將請求從請求隊列移除
function removereqQueue(config){
// 標識值
const requestKey = generateReqKey(config);
if(reqQueue.has(requestKey)){
// 取消之前發(fā)出請求
const cancelToken = reqQueue.get(requestKey);
cancelToken(requestKey);
// 從隊列移除
reqQueue.delete(requestKey);
}
}
??請求攔截器
serviceAxios.interceptors.request.use(
function(config) {
removereqQueue(config); // 檢查是否重復發(fā)送請求
addreqQueue(config); //將本次請求加入請求隊列
return config
},
(error) => {
return Promise.reject(error)
}
)
??響應攔截器
serviceAxios.interceptors.response.use(
(res) => {
removereqQueue(res.config); //請求從請求隊列移除
return res
},
(error) => {
removereqQueue(error.config || {}); //請求從請求隊列移除
//....
}
)
// 最后 export default serviceAxios
baseurl.js代碼如下
const serverConfig = {
baseURL: 'https://fm-emo-music-api.vercel.app',
useTokenAuthorization: true, //是否開啟 token 驗證
}
export default serverConfig
api.js代碼如下
// 引入index.js
import serviceAxios from './index.js'
// get實例
export const VideoRecommendLike = (params) => {
return serviceAxios({
method: "get",
url: "/dj/personalize/recommend",
params,
})
}
// post實例
export const ConfirmPhone = (data) =>{
return serviceAxios({
method: "post",
url: "/captcha/sent",
data,
})
}
調(diào)用
如何在原生js文件內(nèi)調(diào)用?
首先引入axios文件
<!-- axios請求文件 -->
<script src="/src/utils/axios.js"></script>
再引入帶有axios請求的js文件, 請求文件內(nèi)使用es6新語法按需引入api.js文件
例:
import {useRouter} from '../../router/app.js'
如何在Vue文件內(nèi)使用?
示例:
// 按需引入請求接口
import {emailCounts} from "@/api/api.js"
export default {
...
// 異步進行axios請求
methods: {
async comein(){
let res = await emailCount(params)
console.log(res)
}
}
}
總結(jié)
到此這篇關于axios請求二次封裝之避免重復發(fā)送請求的文章就介紹到這了,更多相關axios二次封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Vue3系列之effect和ReactiveEffect?track?trigger源碼解析
這篇文章主要為大家介紹了Vue3系列之effect和ReactiveEffect?track?trigger源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
vue項目中使用AES實現(xiàn)密碼加密解密(ECB和CBC兩種模式)
這篇文章主要介紹了vue項目中使用AES實現(xiàn)密碼加密解密的方法,主要是通過ecb和cbc兩種模式,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-08
利用HBuilder打包前端開發(fā)webapp為apk的方法
下面小編就為大家?guī)硪黄肏Builder打包前端開發(fā)webapp為apk的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11

