摘要:是一個基于的庫,可以用在瀏覽器和中。我在最近的幾個項目中都有使用,并基于根據常見的業務場景封裝了一個通用的服務。業務場景全局請求配置。請求攜帶,權限錯誤統一管理。
axios
axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。
在前端框架中的應用也是特別廣泛,不管是vue還是react,都有很多項目用axios作為網絡請求庫。
我在最近的幾個項目中都有使用axios,并基于axios根據常見的業務場景封裝了一個通用的request服務。
業務場景:
全局請求配置。
get,post,put,delete等請求的promise封裝。
全局請求狀態管理。
取消重復請求。
路由跳轉取消當前頁面請求。
請求攜帶token,權限錯誤統一管理。
默認配置定義全局的默認配置
axios.defaults.timeout = 10000 //超時取消請求 axios.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8" axios.defaults.baseURL = process.env.BASE_URL //掛載在process下的環境常量,在我另一篇文章有詳細說明
如何定義多環境常量
自定義配置(非常見業務場景,僅作介紹)
// 創建實例時設置配置的默認值 var instance = axios.create({ baseURL: "https://api.another.com" }); // 在實例已創建后修改默認值 instance.defaults.headers.common["Authorization"] = AUTH_TOKEN;
優先級:自定義配置 > 默認配置
請求及響應攔截器請求攔截器及取消重復請求
// 請求列表 const requestList = [] // 取消列表 const CancelToken = axios.CancelToken let sources = {} axios.interceptors.request.use((config) => { //將請求地址及參數作為一個完整的請求 const request = JSON.stringify(config.url) + JSON.stringify(config.data) config.cancelToken = new CancelToken((cancel) => { sources[request] = cancel }) //1.判斷請求是否已存在請求列表,避免重復請求,將當前請求添加進請求列表數組; if(requestList.includes(request)){ sources[request]("取消重復請求") }else{ requestList.push(request) //2.請求開始,改變loading狀態供加載動畫使用 store.dispatch("changeGlobalState", {loading: true}) } //3.從store中獲取token并添加到請求頭供后端作權限校驗 const token = store.getters.userInfo.token if (token) { config.headers.token = token } return config }, function (error) { return Promise.reject(error) })
1.請求攔截器中將所有請求添加進請求列表變量,為取消請求及loading狀態管理做準備;當請求列表已存在當前請求則不響應該請求。
2.請求一旦開始,就可以開啟動畫加載效果。
3.用戶登錄后可以在請求頭中攜帶token做權限校驗使用。
響應攔截器
axios.interceptors.response.use(function (response) { // 1.將當前請求中請求列表中刪除 const request = JSON.stringify(response.config.url) + JSON.stringify(response.config.data) requestList.splice(requestList.findIndex(item => item === request), 1) // 2.當請求列表為空時,更改loading狀態 if (requestList.length === 0) { store.dispatch("changeGlobalState", {loading: false}) } // 3.統一處理權限認證錯誤管理 if (response.data.code === 900401) { window.ELEMENT.Message.error("認證失效,請重新登錄!", 1000) router.push("/login") } return response }, function (error) { // 4.處理取消請求 if (axios.isCancel(error)) { requestList.length = 0 store.dispatch("changeGlobalState", {loading: false}) throw new axios.Cancel("cancel request") } else { // 5.處理網絡請求失敗 window.ELEMENT.Message.error("網絡請求失敗", 1000) } return Promise.reject(error) })
1.響應返回后將相應的請求從請求列表中刪除
2.當請求列表為空時,即所有請求結束,加載動畫結束
3.權限認證報錯統一攔截處理
4.取消請求的處理需要結合其他代碼說明
5.由于項目后端并沒有采用RESTful風格的接口請求,200以外都歸為網絡請求失敗
const request = function (url, params, config, method) { return new Promise((resolve, reject) => { axios[method](url, params, Object.assign({}, config)).then(response => { resolve(response.data) }, err => { if (err.Cancel) { console.log(err) } else { reject(err) } }).catch(err => { reject(err) }) }) } const post = (url, params, config = {}) => { return request(url, params, config, "post") } const get = (url, params, config = {}) => { return request(url, params, config, "get") } //3.導出cancel token列表供全局路由守衛使用 export {sources, post, get}
1.axios cancel token API
2.存入需要取消的請求列表導出給導航守衛使用
3.路由發生變化的時候取消當前頁面還沒有返回結果的請求,在復雜的頁面中請求可能會有很多個,增加取消請求的功能可以讓頁面切換的時候不卡頓。
/src/router.js
... import { sources } from "../service/request" ... router.beforeEach((to, from, next) => { document.title = to.meta.title || to.name //路由發生變化時取消當前頁面網絡請求 Object.keys(sources).forEach(item => { sources[item]("取消前頁面請求") }) for (var key in sources) { delete sources[key] } next() })request.js完整代碼:
// 引入網絡請求庫 https://github.com/axios/axios import axios from "axios" import store from "../store" import router from "../router" // 請求列表 const requestList = [] // 取消列表 const CancelToken = axios.CancelToken let sources = {} // axios.defaults.timeout = 10000 axios.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8" axios.defaults.baseURL = process.env.BASE_URL axios.interceptors.request.use((config) => { const request = JSON.stringify(config.url) + JSON.stringify(config.data) config.cancelToken = new CancelToken((cancel) => { sources[request] = cancel }) if(requestList.includes(request)){ sources[request]("取消重復請求") }else{ requestList.push(request) store.dispatch("changeGlobalState", {loading: true}) } const token = store.getters.userInfo.token if (token) { config.headers.token = token } return config }, function (error) { return Promise.reject(error) }) axios.interceptors.response.use(function (response) { const request = JSON.stringify(response.config.url) + JSON.stringify(response.config.data) requestList.splice(requestList.findIndex(item => item === request), 1) if (requestList.length === 0) { store.dispatch("changeGlobalState", {loading: false}) } if (response.data.code === 900401) { window.ELEMENT.Message.error("認證失效,請重新登錄!", 1000) router.push("/login") } return response }, function (error) { if (axios.isCancel(error)) { requestList.length = 0 store.dispatch("changeGlobalState", {loading: false}) throw new axios.Cancel("cancel request") } else { window.ELEMENT.Message.error("網絡請求失敗", 1000) } return Promise.reject(error) }) const request = function (url, params, config, method) { return new Promise((resolve, reject) => { axios[method](url, params, Object.assign({}, config)).then(response => { resolve(response.data) }, err => { if (err.Cancel) { console.log(err) } else { reject(err) } }).catch(err => { reject(err) }) }) } const post = (url, params, config = {}) => { return request(url, params, config, "post") } const get = (url, params, config = {}) => { return request(url, params, config, "get") } export {sources, post, get}
以上。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108504.html
摘要:時隔一年再次更新下根據項目下常見業務場景對的二次封裝功能實現兼容瀏覽器避免緩存減少或更新重復請求接口域名使用環境變量全局狀態可關閉的全局錯誤提醒可開啟攜帶全局分頁參數攔截器請求攔截器請求開始請求出錯響應攔截器請求結束請求錯誤處理網絡請求中, 時隔一年再次更新下根據vue項目下常見業務場景對axios的二次封裝 功能實現:1.兼容ie瀏覽器避免緩存2.減少或更新重復請求3.接口域名使用環...
摘要:攔截重復請求如何標識每個請求下面函數,通過一個請求參數中的請求傳遞參數或請求傳遞參數來表示每一個請求。 一直想封裝一下 axios, 可以方便項目中使用,今天有時間,就好好研究了一下。 源碼: // util/axios.js import axios from axios const pending = {} const CancelToken = axios.CancelTok...
摘要:并且數據同步后默認會保存下來,這樣下次再請求時存儲層中就有數據了。以下參數會傳到中這么一來,存儲層就和接口層對接起來了。五支持永久保存在某些場景下,可能不方便寫過期時間,這時默認可以傳遞,標記該數據永不過期。 零、問題的由來 開門見山地說,這篇文章【又】是一篇安利軟文~,安利的對象就是 tua-storage。 顧名思義,這就是一款存儲數據的工具。 用 tua-storage 好處大大...
摘要:使用了攔截器處理相關問題,這樣就不再需要使用來做錯誤的處理。萬惡的攔截器一些處理無論是對成功的處理還是對失敗的處理,如果攔截器不拋出錯誤,那么終將還會執行里面處理請求成功的函數,即使你返回。 一 前言 本文適合剛接觸axios或者使用過幾次的同學來分享交流一些入門經驗,本文同樣適用熟悉axios的同學來作為參考手冊。默認你已經看過axios的相關文檔:axios文檔 GitHub,通過...
摘要:是在收到響應后執行的函數,可以不用返回。一步步介紹了如何構建以及使用中間層,來統一管理接口地址,最后還介紹了下中間件等高級功能。 零、問題的由來 開門見山地說,這篇文章是一篇安利軟文~,安利的對象就是最近搞的 tua-api。 顧名思義,這就是一款輔助獲取接口數據的工具。 發請求相關的工具辣么多,那我為啥要用你呢? 理想狀態下,項目中應該有一個 api 中間層。各種接口在這里定義,業務...
閱讀 878·2021-10-13 09:39
閱讀 3531·2021-09-26 10:16
閱讀 2860·2019-08-30 15:54
閱讀 1037·2019-08-30 14:22
閱讀 2886·2019-08-29 15:39
閱讀 3253·2019-08-27 10:52
閱讀 809·2019-08-26 13:59
閱讀 1703·2019-08-26 12:20