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