【Vue 中 Axios 的封裝和 API 接口的管理】

2022-12-27 14:09:27 來源:51CTO博客


(相關資料圖)

一. 封裝各模塊作用

引入一般我會在項目的src目錄中,新建一個request文件夾,然后在里面新建一個http.js和一個api.js文件。http.js文件用來封裝我們的axios,api.js用來統一管理我們的接口。環境切換我們的項目環境可能有開發環境、測試環境和生產環境。我們通過node的環境變量來匹配我們的默認的接口url前綴。axios.defaults.baseURL可以設置axios的默認請求地址就不多說了
if (process.env.NODE_ENV == "development") {        axios.defaults.baseURL = "/api";} else if (process.env.NODE_ENV == "debug") {        axios.defaults.baseURL = "";} else if (process.env.NODE_ENV == "production") {        axios.defaults.baseURL = "http://api.123dailu.com/";}
請求頭的默認配置通過axios.defaults.timeout設置默認的請求超時時間。例如超過了10s,就會告知用戶當前請求超時,請刷新等。 通過設置 withCredentials: true ,發送Ajax時,Request header中便會帶上 Cookie 信息。 post請求的時候,我們需要加上一個請求頭,所以可以在這里進行一個默認的設置,即設置post的請求頭為application/x-www-form-urlencoded;charset=UTF-8
// 請求超時時間axios.defaults.timeout = 10000;// 在客戶端axios請求中設置axios.defaults.withCredentials = true// 通過設置 withCredentials: true ,發送Ajax時,Request header中便會帶上 Cookie 信息。// post請求頭axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8";
請求攔截器我們在發送請求前可以進行一個請求的攔截,為什么要攔截呢,我們攔截請求是用來做什么的呢?比如,有些請求是需要用戶登錄之后才能訪問的,或者post請求的時候,我們需要序列化我們提交的數據。這時候,我們可以在請求被發送之前進行一個攔截,從而進行我們想要的操作。
// 請求攔截器axios.interceptors.request.use(        config => {        // 每次發送請求之前判斷是否存在token,如果存在,則統一在http請求的header都加上token,不用每次請求都手動添加了        // 即使本地存在token,也有可能token是過期的,所以在響應攔截器中要對返回狀態進行判斷        const token = store.state.token;                token && (config.headers.Authorization = token);                return config;        },        error => {                return Promise.error(error);        })

注意:

這里說一下token,一般是在登錄完成之后,將用戶的token通過localStorage或者cookie存在本地,然后用戶每次在進入頁面的時候(即在main.js中),會首先從本地存儲中讀取token,如果token存在說明用戶已經登陸過,則更新vuex中的token狀態。然后,在每次請求接口的時候,都會在請求的header中攜帶token,后臺人員就可以根據你攜帶的token來判斷你的登錄是否過期,如果沒有攜帶,則說明沒有登錄過。這時候或許有些小伙伴會有疑問了,就是每個請求都攜帶token,那么要是一個頁面不需要用戶登錄就可以訪問的怎么辦呢?其實,你前端的請求可以攜帶token,但是后臺可以選擇不接收??!

響應攔截器響應攔截器很好理解,就是服務器返回給我們的數據,我們在拿到之前可以對他進行一些處理。例如上面的思想:如果后臺返回的狀態碼是200,則正常返回數據,否則的根據錯誤的狀態碼類型進行一些我們需要的錯誤,其實這里主要就是進行了錯誤的統一處理和沒登錄或登錄過期后調整登錄頁的一個操作。
// 響應攔截器axios.interceptors.response.use(        response => {                if (response.status === 200) {                        return Promise.resolve(response);                } else {                        return Promise.reject(response);                }        },    // 服務器狀態碼不是200的情況        error => {                if (error.response.status) {                        switch (error.response.status) {                                // 401: 未登錄                                // 未登錄則跳轉登錄頁面,并攜帶當前頁面的路徑                                // 在登錄成功后返回當前頁面,這一步需要在登錄頁操作。                                case 401:                                        router.replace({                                                path: "/login",                                                query: { redirect: router.currentRoute.fullPath }                     });                    break;                // 403 token過期                                // 登錄過期對用戶進行提示                                // 清除本地token和清空vuex中token對象                                // 跳轉登錄頁面                                case 403:                                         Toast({                                                message: "登錄過期,請重新登錄",                                                duration: 1000,                                                forbidClick: true                                        });                                        // 清除token                                        localStorage.removeItem("token");                                        store.commit("loginSuccess", null);                                        // 跳轉登錄頁面,并將要瀏覽的頁面fullPath傳過去,登錄成功后跳轉需要訪問的頁面                    setTimeout(() => {                                                router.replace({                                                        path: "/login",                                                        query: {                                 redirect: router.currentRoute.fullPath                             }                                                });                                        }, 1000);                                        break;                 // 404請求不存在                                case 404:                                        Toast({                                                message: "網絡請求不存在",                                                duration: 1500,                                                forbidClick: true                                        });                                    break;                                // 其他錯誤,直接拋出錯誤提示                                default:                                        Toast({                                                message: error.response.data.message,                                                duration: 1500,                                                forbidClick: true                                        });                        }                        return Promise.reject(error.response);                }           });

二. 封裝后代碼

/**axios封裝 * 請求攔截、相應攔截、錯誤統一處理 */import axios from "axios"; import QS from "qs";import { Toast } from "vant";import store from "../store/index"http:// 環境的切換if (process.env.NODE_ENV == "development") {        axios.defaults.baseURL = "/api";} else if (process.env.NODE_ENV == "debug") {        axios.defaults.baseURL = "";} else if (process.env.NODE_ENV == "production") {        axios.defaults.baseURL = "http://api.123dailu.com/";}// 請求超時時間axios.defaults.timeout = 10000;// 在客戶端axios請求中設置axios.defaults.withCredentials = true// 通過設置 withCredentials: true ,發送Ajax時,Request header中便會帶上 Cookie 信息。// post請求頭axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8";// 請求攔截器axios.interceptors.request.use(        config => {        // 每次發送請求之前判斷是否存在token,如果存在,則統一在http請求的header都加上token,不用每次請求都手動添加了        // 即使本地存在token,也有可能token是過期的,所以在響應攔截器中要對返回狀態進行判斷        const token = store.state.token;                token && (config.headers.Authorization = token);                return config;        },        error => {                return Promise.error(error);        })// 響應攔截器axios.interceptors.response.use(        response => {                if (response.status === 200) {                        return Promise.resolve(response);                } else {                        return Promise.reject(response);                }        },    // 服務器狀態碼不是200的情況        error => {                if (error.response.status) {                        switch (error.response.status) {                                // 401: 未登錄                                // 未登錄則跳轉登錄頁面,并攜帶當前頁面的路徑                                // 在登錄成功后返回當前頁面,這一步需要在登錄頁操作。                                case 401:                                        router.replace({                                                path: "/login",                                                query: { redirect: router.currentRoute.fullPath }                     });                    break;                // 403 token過期                                // 登錄過期對用戶進行提示                                // 清除本地token和清空vuex中token對象                                // 跳轉登錄頁面                                case 403:                                         Toast({                                                message: "登錄過期,請重新登錄",                                                duration: 1000,                                                forbidClick: true                                        });                                        // 清除token                                        localStorage.removeItem("token");                                        store.commit("loginSuccess", null);                                        // 跳轉登錄頁面,并將要瀏覽的頁面fullPath傳過去,登錄成功后跳轉需要訪問的頁面                    setTimeout(() => {                                                router.replace({                                                        path: "/login",                                                        query: {                                 redirect: router.currentRoute.fullPath                             }                                                });                                        }, 1000);                                        break;                 // 404請求不存在                                case 404:                                        Toast({                                                message: "網絡請求不存在",                                                duration: 1500,                                                forbidClick: true                                        });                                    break;                                // 其他錯誤,直接拋出錯誤提示                                default:                                        Toast({                                                message: error.response.data.message,                                                duration: 1500,                                                forbidClick: true                                        });                        }                        return Promise.reject(error.response);                }           });/**  * get方法,對應get請求  * @param {String} url [請求的url地址]  * @param {Object} params [請求時攜帶的參數]  */export function get(url, params){        return new Promise((resolve, reject) =>{                axios.get(url, {                        params: params                })                .then(res => {                        resolve(res.data);                })                .catch(err => {                        reject(err.data)                })        });}/**  * post方法,對應post請求  * @param {String} url [請求的url地址]  * @param {Object} params [請求時攜帶的參數]  */export function post(url, params) {        return new Promise((resolve, reject) => {                 axios.post(url, QS.stringify(params))                .then(res => {                        resolve(res.data);                })                .catch(err => {                        reject(err.data)                })        });}

三. http.js和 api.js

http.js是封裝好的axios, api.js 是把業務中接口 統一放在這個文件里,具體根據項目進行定制化的封裝可以參考??axios封裝??

標簽: 登錄成功 發送請求 我們需要

上一篇:【環球熱聞】【Vue2.0與Vue3.0區別總結】
下一篇:#yyds干貨盤點# LeetCode程序員面試金典:插入