欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

axios的interceptors多次執(zhí)行問題解決

 更新時間:2022年06月16日 15:33:38   作者:Gaby  
這篇文章主要為大家介紹了axios中interceptors多次執(zhí)行問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

問題

在進(jìn)行 axios 封裝的時候,遇到個問題,就是每次發(fā)起請求時axios 都會執(zhí)行兩次響應(yīng)攔截,甚是納悶,一時理不出思路來。

代碼如下:

class Http {
    constructor(config) {
        this.axios = axios;
        this.axiosInterceptor = undefined;
        // 公共的 header
        let defaultHeaders = {
            'Content-Type': 'application/json;charset=UTF-8',
            'Accept': 'application/json', // 通過頭指定,獲取的數(shù)據(jù)類型是JSON 'application/json, text/plain, */*',
            'x-end-point': '.10.'
        }
        if(config?.headers){
            for (let i in config.headers) {
                defaultHeaders[i] = config.headers[i];
            }
        }
        axios({
            // `baseURL` 將自動加在 `url` 前面,除非 `url` 是一個絕對 URL。
            // 它可以通過設(shè)置一個 `baseURL` 便于為 axios 實(shí)例的方法傳遞相對 URL
            baseURL: config?.baseURL,
            // `url` 是用于請求的服務(wù)器 URL
            url: config?.url,
            // `method` 是創(chuàng)建請求時使用的方法
            method: config?.method || 'get',
            // `headers` 是即將被發(fā)送的自定義請求頭
            headers: {...defaultHeaders},
            // `params` 是即將與請求一起發(fā)送的 URL 參數(shù)
            // 必須是一個無格式對象(plain object)或 URLSearchParams 對象
            params: config?.method === 'get' ? config?.params || {} : {},
            // `paramsSerializer` 是一個負(fù)責(zé) `params` 序列化的函數(shù)
            // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
            paramsSerializer: function(params) {
                return Qs.stringify(params, {arrayFormat: 'brackets'})
            },
            // `data` 是作為請求主體被發(fā)送的數(shù)據(jù)
            // 只適用于這些請求方法 'PUT', 'POST', 和 'PATCH'
            // 在沒有設(shè)置 `transformRequest` 時,必須是以下類型之一:
            // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
            // - 瀏覽器專屬:FormData, File, Blob
            // - Node 專屬: Stream
            data: config?.method === 'post' ? config?.params || {} : {},
            // `timeout` 指定請求超時的毫秒數(shù)(0 表示無超時時間)
            // 如果請求話費(fèi)了超過 `timeout` 的時間,請求將被中斷
            timeout: 0,
            // `withCredentials` 表示跨域請求時是否需要使用憑證
            withCredentials: false, // default 為true則產(chǎn)生跨域,跨域攜帶cookie
            // `responseType` 表示服務(wù)器響應(yīng)的數(shù)據(jù)類型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
            responseType: 'json', // default
        });
        // 添加請求攔截器
        axios.interceptors.request.use( (config) =>  {
            // 在發(fā)送請求之前做些什么
            return config;
        }, function (error) {
            // 對請求錯誤做些什么
            return Promise.reject(error);
        });
        // 添加響應(yīng)攔截器
        axios.interceptors.response.use((res) => {
            const { status, data } = res;
            // 對錯誤狀態(tài)提示進(jìn)行處理
            let message = ''
            if (status < 200 || status >= 300) {
                // 處理http錯誤,拋到業(yè)務(wù)代碼
                message = this.showResState(status)
                if (typeof res.data === 'string') {
                    res.data = {code:status, message }
                } else {
                    res.data.code = status
                    res.data.message = message
                }
            }
        return res.data;
        }, function (error) {
            // 對響應(yīng)錯誤做點(diǎn)什么
            return Promise.reject(error);
        });
    }
    get(url,params={}){
        // 為給定 ID 的 user 創(chuàng)建請求
        return new Promise((resolve, reject) => {
            this.axios.get(url,{
                params
            }).then(response => {
                // 2. 如果成功了, 調(diào)用resolve(value)
                resolve(response);
            })
                .catch(error => {
                    // 3. 如果失敗了, 不調(diào)用reject(reason), 而是提示異常信息
                    reject(error)
                    // message.error('請求出錯了: ' + error.message).then(r => {});
                }).finally(() => {
            })
        });
    }
    post(url,params={}){
        return new Promise((resolve, reject) => {
            this.axios.post(url, params).then(response => {
                // 2. 如果成功了, 調(diào)用resolve(value)
                resolve(response);
            })
                .catch(error => {
                    // 3. 如果失敗了, 不調(diào)用reject(reason), 而是提示異常信息
                    reject(error)
                    // message.error('請求出錯了: ' + error.message).then(r => {});
                }).finally(() => {
            })
        });
    }
    showResState (state) {
        let message = '';
        // 這里只做部分常見的示例,具體根據(jù)需要進(jìn)行配置
        switch (state) {
            case 400:
                message = '請求錯誤(400)'
                break
            case 401:
                message = '未授權(quán),請重新登錄(401)'
                break
            case 403:
                message = '拒絕訪問(403)'
                break
            case 404:
                message = '請求出錯(404)'
                break
            case 500:
                message = '服務(wù)器錯誤(500)'
                break
            case 501:
                message = '服務(wù)未實(shí)現(xiàn)(501)'
                break
            case 502:
                message = '網(wǎng)絡(luò)錯誤(502)'
                break
            case 503:
                message = '服務(wù)不可用(503)'
                break
            default:
                message = `連接出錯(${state})!`
        }
        return `${message},請檢查網(wǎng)絡(luò)或聯(lián)系網(wǎng)站管理員!`
    }
    // 插件初始化時會傳入所需的配置項
    autoAddToken (config) {
        // 在請求階段時修改 config 配置項為其添加 token 具體屬性名稱可自定義
        config.headers ??= {}
        config.headers.Authorization = localStorage.token || null
        return config
    }
}
export default Http;

可能遇到過該類問題的小伙伴們一眼就看出問題所在,對于未有碰到過這個問題的小伙伴,可能就又點(diǎn)煎熬了。

原因

若你使用use,就像Node.js里的use那樣,會不斷地往axios對象添加interceptors,由于我將該攔截器放在函數(shù)內(nèi),只要函數(shù)被執(zhí)行,則會再次將攔截器函數(shù)增添到axios對象上。

所以,推薦的辦法是,將攔截器放在函數(shù)外,可我的需求決定了,我必須將它放在函數(shù)內(nèi),那么該如何解決呢?

解決

添加該文件內(nèi)的唯一變量標(biāo)識符let interceptor = null,進(jìn)行判斷,只要攔截器存在,則不會繼續(xù)添加,部分代碼如下所示:

if (!this.interceptor) {
// 添加響應(yīng)攔截器
this.interceptor = axios.interceptors.response.use((res) => {
        const { status, data } = res;
        // 對錯誤狀態(tài)提示進(jìn)行處理
        let message = ''
        if (status < 200 || status >= 300) {
            // 處理http錯誤,拋到業(yè)務(wù)代碼
            message = this.showResState(status)
            if (typeof res.data === 'string') {
                res.data = {code:status, message }
            } else {
                res.data.code = status
                res.data.message = message
            }
        }
    return res.data;
    }, function (error) {
        // 對響應(yīng)錯誤做點(diǎn)什么
        return Promise.reject(error);
    });
  }

奈何不好使。不得一不得不把攔截器提取到類外部,問題解決。

這里只貼部分主要代碼:

import axios from "axios";
/* 將攔截器 置于封裝類之外 */
// 添加請求攔截器
axios.interceptors.request.use( (config) =>  {
    // 在發(fā)送請求之前做些什么 添加 token 等鑒權(quán)功能
    //...
    return config;
}, function (error) {
    // 對請求錯誤做些什么
    return Promise.reject(error);
});
// 添加響應(yīng)攔截器
axios.interceptors.response.use((res) => {
    const { status } = res;
    // 在發(fā)送結(jié)果之前做些什么  對錯誤狀態(tài)提示進(jìn)行處理
    //...
    return res.data;
}, function (error) {
    // 對響應(yīng)錯誤做點(diǎn)什么
    return Promise.reject(error);
});
class Http {
    constructor(config) {
        this.axios = axios;
        // 這里仍需對配置進(jìn)行處理,代碼省略了
        this.config = config;
    }
    // Get 請求
    get(url,params={},headers={}){
        // ...
    }
    // POST 請求
    post(url,params={},headers={}){
        // ...
    }
}
export default Http;
// 無特殊需求的只需使用這個一個對象即可 公共 header 可在此配置, 如需多個實(shí)例 可按照此方式創(chuàng)建多個進(jìn)行導(dǎo)出
export const Axios = new Http({
    headers: {
        'x-http-token': 'xxx'
    }
});

這里不對具體的方法進(jìn)行描述,只做一個解決問題的說明,后續(xù)會針對 axios 類的封裝,單獨(dú)寫篇文章再詳細(xì)說明下的

以上就是axios的interceptors多次執(zhí)行問題解決的詳細(xì)內(nèi)容,更多關(guān)于axios interceptors多次執(zhí)行的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue路由跳轉(zhuǎn)的5種方式及擴(kuò)展

    Vue路由跳轉(zhuǎn)的5種方式及擴(kuò)展

    這篇文章主要給大家介紹了關(guān)于Vue路由跳轉(zhuǎn)的5種方式及擴(kuò)展,在Vue中路由是一種用于導(dǎo)航和管理頁面之間跳轉(zhuǎn)的機(jī)制,Vue Router是Vue官方提供的路由管理器,需要的朋友可以參考下
    2023-11-11
  • Vue.js中的計算屬性、監(jiān)視屬性與生命周期詳解

    Vue.js中的計算屬性、監(jiān)視屬性與生命周期詳解

    最近在學(xué)習(xí)vue,學(xué)習(xí)中遇到了一些感覺挺重要的知識點(diǎn),感覺有必要整理下來,這篇文章主要給大家介紹了關(guān)于Vue.js中計算屬性、監(jiān)視屬性與生命周期的相關(guān)資料,需要的朋友可以參考下
    2021-06-06
  • vue項目中Toast字體過小,沒有邊距的解決方案

    vue項目中Toast字體過小,沒有邊距的解決方案

    這篇文章主要介紹了vue項目中Toast字體過小,沒有邊距的解決方案。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • 詳解vue2.0模擬后臺json數(shù)據(jù)

    詳解vue2.0模擬后臺json數(shù)據(jù)

    這篇文章主要介紹了vue2.0模擬后臺json數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • vue項目熱更新的坑及解決

    vue項目熱更新的坑及解決

    這篇文章主要介紹了vue項目熱更新的坑及解決方案,具有很好的參考價值,希望對的大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue和iview結(jié)合動態(tài)生成表單實(shí)例

    vue和iview結(jié)合動態(tài)生成表單實(shí)例

    這篇文章主要介紹了vue和iview結(jié)合動態(tài)生成表單實(shí)例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue項目配置同一局域網(wǎng)可使用ip訪問的操作

    vue項目配置同一局域網(wǎng)可使用ip訪問的操作

    這篇文章主要介紹了vue項目配置同一局域網(wǎng)可使用ip訪問的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Vue Element前端應(yīng)用開發(fā)之echarts圖表

    Vue Element前端應(yīng)用開發(fā)之echarts圖表

    在我們做應(yīng)用系統(tǒng)的時候,往往都會涉及圖表的展示,綜合的圖表展示能夠給客戶帶來視覺的享受和數(shù)據(jù)直觀體驗(yàn),同時也是增強(qiáng)客戶認(rèn)同感的舉措之一
    2021-05-05
  • Vue驗(yàn)證碼60秒倒計時功能簡單實(shí)例代碼

    Vue驗(yàn)證碼60秒倒計時功能簡單實(shí)例代碼

    這篇文章主要介紹了Vue驗(yàn)證碼60秒倒計時功能簡單實(shí)例代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • vue cli webpack中使用sass的方法

    vue cli webpack中使用sass的方法

    這篇文章主要介紹了vue cli webpack中使用sass的方法,需要的朋友可以參考下
    2018-02-02

最新評論