摘要:攔截重復(fù)請(qǐng)求如何標(biāo)識(shí)每個(gè)請(qǐng)求下面函數(shù),通過一個(gè)請(qǐng)求參數(shù)中的請(qǐng)求傳遞參數(shù)或請(qǐng)求傳遞參數(shù)來表示每一個(gè)請(qǐng)求。
一直想封裝一下 axios, 可以方便項(xiàng)目中使用,今天有時(shí)間,就好好研究了一下。
源碼:// util/axios.js import axios from "axios" const pending = {} const CancelToken = axios.CancelToken const removePending = (key, isRequest = false) => { if (pending[key] && isRequest) { pending[key]("取消重復(fù)請(qǐng)求") } delete pending[key] } const getRequestIdentify = (config, isReuest = false) => { let url = config.url if (isReuest) { url = config.baseURL + config.url.substring(1, config.url.length) } return config.method === "get" ? encodeURIComponent(url + JSON.stringify(config.params)) : encodeURIComponent(config.url + JSON.stringify(config.data)) } // 請(qǐng)求攔截器 axios.interceptors.request.use(config => { // 攔截重復(fù)請(qǐng)求(即當(dāng)前正在進(jìn)行的相同請(qǐng)求) let requestData = getRequestIdentify(config, true) removePending(requestData, true) config.cancelToken = new CancelToken((c) => { pending[requestData] = c }) return config }, error => { return Promise.reject(error) }) // 異常處理 axios.interceptors.response.use(response => { // 把已經(jīng)完成的請(qǐng)求從 pending 中移除 let requestData = getRequestIdentify(response.config) removePending(requestData) return { code: response.status, message: response.statusText, data: response.data } }, err => { if (err && err.response) { switch (err.response.status) { case 400: err.message = "錯(cuò)誤請(qǐng)求" break case 401: err.message = "未授權(quán),請(qǐng)重新登錄" break case 403: err.message = "拒絕訪問" break case 404: err.message = "請(qǐng)求錯(cuò)誤,未找到該資源" break case 405: err.message = "請(qǐng)求方法未允許" break case 408: err.message = "請(qǐng)求超時(shí)" break case 500: err.message = "服務(wù)器端出錯(cuò)" break case 501: err.message = "網(wǎng)絡(luò)未實(shí)現(xiàn)" break case 502: err.message = "網(wǎng)絡(luò)錯(cuò)誤" break case 503: err.message = "服務(wù)不可用" break case 504: err.message = "網(wǎng)絡(luò)超時(shí)" break case 505: err.message = "http版本不支持該請(qǐng)求" break default: err.message = `連接錯(cuò)誤${err.response.status}` } let errData = { code: err.response.status, message: err.message } // 統(tǒng)一錯(cuò)誤處理可以放這,例如頁面提示錯(cuò)誤... console.log("統(tǒng)一錯(cuò)誤處理: ", errData) } return Promise.reject(err) }) axios.defaults.baseURL = "http://localhost:3000/" export default (instance) => { instance.prototype.axios = (data) => { var _params = { method: !data.method ? "get" : data.method.toLowerCase(), url: data.url } if (_params.method === "get") { _params.params = data.params || {} } else { _params.data = data.params || {} } return new Promise((resolve, reject) => { axios(_params).then(response => { resolve(response) }).catch(error => { reject(error) }) }) } }調(diào)用:
// main.js import axios from "./util/axios" Vue.use(axios)
// HelloWorld.vue methods: { getUserInfo (_id) { this.axios({ url: "/users", method: "get", params: { "id": _id } }).then(response => { console.log(response) }) } }說明: 全局的 axios 默認(rèn)值
本人使用 json-server 搭建 mock 服務(wù)(這個(gè),有必要的話,之后會(huì)寫一下),服務(wù)器地址為http://localhost:3000/,所以設(shè)置 axios 的 基礎(chǔ)URL路徑設(shè)置為http://localhost:3000/。
另外,大家有需要的話,也可以對(duì) axios.defaults.headers 默認(rèn)的請(qǐng)求頭、axios.defaults.timeout請(qǐng)求超時(shí)時(shí)間 進(jìn)行設(shè)置。這里就不設(shè)置了。
axios.defaults.baseURL = "http://localhost:3000/"get、post請(qǐng)求的封裝
這里,get、post 請(qǐng)求具體調(diào)用的時(shí)候,都通過 this.axios(requestData)來調(diào)用,其中 requestData有統(tǒng)一的格式,如下
const requestData = { url: "/users", // 必填 method: "get", // 選填,默認(rèn) "get" params: {} // 選填,默認(rèn) {} }
這部分通過 requestData.method處理 axios發(fā)送請(qǐng)求時(shí),requestData.params 是賦值給 _params.params(get 請(qǐng)求傳遞參數(shù)) 還是賦值給 _params.data(post 請(qǐng)求傳遞參數(shù))。
export default (instance) => { instance.prototype.axios = (data) => { var _params = { method: !data.method ? "get" : data.method.toLowerCase(), url: data.url } if (_params.method === "get") { _params.params = data.params || {} } else { _params.data = data.params || {} } return new Promise((resolve, reject) => { axios(_params).then(response => { resolve(response) }).catch(error => { reject(error) }) }) } }攔截重復(fù)請(qǐng)求 如何標(biāo)識(shí)每個(gè)請(qǐng)求
下面函數(shù),通過一個(gè)請(qǐng)求參數(shù)中的 url, params(get 請(qǐng)求傳遞參數(shù))或 data(post 請(qǐng)求傳遞參數(shù))來表示每一個(gè)請(qǐng)求。
使用請(qǐng)求路徑加請(qǐng)求參數(shù)的標(biāo)識(shí)方式,避免了相同請(qǐng)求路徑,不同請(qǐng)求參數(shù)的情況下的錯(cuò)誤攔截。
其中需要注意的地方是,請(qǐng)求攔截器中 config.url = "/users", 響應(yīng)攔截器中 config.url = "http://localhost:3000/users",所以加上一個(gè)標(biāo)識(shí)isReuest來計(jì)算請(qǐng)求的全路徑
/** * config: 請(qǐng)求數(shù)據(jù) * isReuest: 請(qǐng)求攔截器中 config.url = "/users", 響應(yīng)攔截器中 config.url = "http://localhost:3000/users",所以加上一個(gè)標(biāo)識(shí)來計(jì)算請(qǐng)求的全路徑 */ const getRequestIdentify = (config, isReuest = false) => { let url = config.url if (isReuest) { url = config.baseURL + config.url.substring(1, config.url.length) } return config.method === "get" ? encodeURIComponent(url + JSON.stringify(config.params)) : encodeURIComponent(config.url + JSON.stringify(config.data)) }請(qǐng)求攔截器
使用 cancel token 取消請(qǐng)求。
這里每個(gè)請(qǐng)求通過傳遞一個(gè) executor 函數(shù)到 CancelToken 的構(gòu)造函數(shù)來創(chuàng)建 cancel token。
// 添加請(qǐng)求攔截器 axios.interceptors.request.use(config => { // 發(fā)送請(qǐng)求之前,攔截重復(fù)請(qǐng)求(即當(dāng)前正在進(jìn)行的相同請(qǐng)求) let requestData = getRequestIdentify(config, true) removePending(requestData, true) config.cancelToken = new CancelToken((c) => { pending[requestData] = c }) return config }, error => { return Promise.reject(error) })取消請(qǐng)求
這一步是結(jié)合上面的請(qǐng)求攔截器執(zhí)行的,取消重復(fù)請(qǐng)求的同時(shí)刪除記錄,并且在下面的響應(yīng)攔截器也會(huì)調(diào)用該函數(shù),即完成請(qǐng)求后刪除請(qǐng)求記錄。
// key: 請(qǐng)求標(biāo)識(shí);isRequest 完成請(qǐng)求后也需要執(zhí)行刪除記錄,所以添加此參數(shù)避免執(zhí)行無用操作 const removePending = (key, isRequest = false) => { if (pending[key] && isRequest) { pending[key]("取消重復(fù)請(qǐng)求") } delete pending[key] // 把這條記錄從 pending 中移除 }請(qǐng)求異常處理
可以使用響應(yīng)攔截器來統(tǒng)一處理請(qǐng)求異常,例如,統(tǒng)一返回的數(shù)據(jù)的格式、統(tǒng)一處理異常報(bào)錯(cuò)...
// 異常處理 axios.interceptors.response.use(response => { // 把已經(jīng)完成的請(qǐng)求從 pending 中移除 let requestData = getRequestIdentify(response.config) removePending(requestData) return { code: response.status, message: response.statusText, data: response.data } }, err => { if (err && err.response) { switch (err.response.status) { case 400: err.message = "錯(cuò)誤請(qǐng)求" break case 401: err.message = "未授權(quán),請(qǐng)重新登錄" break case 403: err.message = "拒絕訪問" break case 404: err.message = "請(qǐng)求錯(cuò)誤,未找到該資源" break case 405: err.message = "請(qǐng)求方法未允許" break case 408: err.message = "請(qǐng)求超時(shí)" break case 500: err.message = "服務(wù)器端出錯(cuò)" break case 501: err.message = "網(wǎng)絡(luò)未實(shí)現(xiàn)" break case 502: err.message = "網(wǎng)絡(luò)錯(cuò)誤" break case 503: err.message = "服務(wù)不可用" break case 504: err.message = "網(wǎng)絡(luò)超時(shí)" break case 505: err.message = "http版本不支持該請(qǐng)求" break default: err.message = `連接錯(cuò)誤${err.response.status}` } let errData = { code: err.response.status, message: err.message } // 統(tǒng)一錯(cuò)誤處理可以放這,例如頁面提示錯(cuò)誤... console.log("統(tǒng)一錯(cuò)誤處理: ", errData) } return Promise.reject(err) })疑問:
CancelToken 這一部分,還不是很清楚原理,希望大家指導(dǎo)一下~~~
參考地址:axios 的 github 地址
https://segmentfault.com/a/11...
https://www.jianshu.com/p/444...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/97903.html
摘要:是一個(gè)基于的庫,可以用在瀏覽器和中。我在最近的幾個(gè)項(xiàng)目中都有使用,并基于根據(jù)常見的業(yè)務(wù)場景封裝了一個(gè)通用的服務(wù)。業(yè)務(wù)場景全局請(qǐng)求配置。請(qǐng)求攜帶,權(quán)限錯(cuò)誤統(tǒng)一管理。 axios axios 是一個(gè)基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。在前端框架中的應(yīng)用也是特別廣泛,不管是vue還是react,都有很多項(xiàng)目用axios作為網(wǎng)絡(luò)請(qǐng)求庫。我在最近的幾個(gè)項(xiàng)...
摘要:時(shí)隔一年再次更新下根據(jù)項(xiàng)目下常見業(yè)務(wù)場景對(duì)的二次封裝功能實(shí)現(xiàn)兼容瀏覽器避免緩存減少或更新重復(fù)請(qǐng)求接口域名使用環(huán)境變量全局狀態(tài)可關(guān)閉的全局錯(cuò)誤提醒可開啟攜帶全局分頁參數(shù)攔截器請(qǐng)求攔截器請(qǐng)求開始請(qǐng)求出錯(cuò)響應(yīng)攔截器請(qǐng)求結(jié)束請(qǐng)求錯(cuò)誤處理網(wǎng)絡(luò)請(qǐng)求中, 時(shí)隔一年再次更新下根據(jù)vue項(xiàng)目下常見業(yè)務(wù)場景對(duì)axios的二次封裝 功能實(shí)現(xiàn):1.兼容ie瀏覽器避免緩存2.減少或更新重復(fù)請(qǐng)求3.接口域名使用環(huán)...
摘要:使用了攔截器處理相關(guān)問題,這樣就不再需要使用來做錯(cuò)誤的處理。萬惡的攔截器一些處理無論是對(duì)成功的處理還是對(duì)失敗的處理,如果攔截器不拋出錯(cuò)誤,那么終將還會(huì)執(zhí)行里面處理請(qǐng)求成功的函數(shù),即使你返回。 一 前言 本文適合剛接觸axios或者使用過幾次的同學(xué)來分享交流一些入門經(jīng)驗(yàn),本文同樣適用熟悉axios的同學(xué)來作為參考手冊(cè)。默認(rèn)你已經(jīng)看過axios的相關(guān)文檔:axios文檔 GitHub,通過...
摘要:給用戶以提示,在封裝對(duì)應(yīng)的或者的時(shí)候把一些固定必傳的參數(shù)加上去,寫其他請(qǐng)求時(shí)加上改請(qǐng)求的其他參數(shù)就好了超時(shí)的設(shè)置,以及超時(shí)后的一些處理,是重新請(qǐng)求還是做其他操作。 import axios from axios import qs from qs import ErrorCode from ./error//封裝code錯(cuò)誤時(shí)對(duì)應(yīng)的提示 import router from ../ro...
摘要:基本開發(fā)環(huán)境創(chuàng)建的項(xiàng)目,作為代碼編寫工具插件推薦插件配置文章目錄項(xiàng)目目錄結(jié)構(gòu)介紹框架選擇處理請(qǐng)求二次封裝項(xiàng)目目錄結(jié)構(gòu)簡介業(yè)務(wù)相關(guān)靜態(tài)文件全局組件基礎(chǔ)樣式布局樣式及工具引入請(qǐng)求配置路由全局狀態(tài)管理工具文件入口文件主要配置文件頁面檢查配置測試 基本開發(fā)環(huán)境 vue-cli3 創(chuàng)建的項(xiàng)目,vscode 作為代碼編寫工具vscode插件推薦:vscode 插件配置 文章目錄 項(xiàng)目目錄結(jié)構(gòu)介紹...
閱讀 1017·2021-11-16 11:45
閱讀 2194·2021-10-09 09:44
閱讀 1415·2019-08-30 14:03
閱讀 1219·2019-08-26 18:28
閱讀 3391·2019-08-26 13:50
閱讀 1794·2019-08-23 18:38
閱讀 3507·2019-08-23 18:22
閱讀 3673·2019-08-23 15:27