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

從axios源碼角度解決bug的過程記錄

 更新時間:2022年12月15日 14:28:27   作者:chenjianzhong  
這篇文章主要為大家介紹了從axios源碼角度解決bug的過程記錄,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

現(xiàn)象

公司的一個 H5 站點在頭條 App 里白屏,在手百、QQ 瀏覽器、Safari、Chrome 等都正常

排查思路

1. 引入 vConsole 在移動端調(diào)試

因為移動端沒有 PC 里那樣方便的調(diào)試工具可以清晰的查看 log 和 network 之類有用的信息,只能借助 vConsole、eruda 這類移動端調(diào)試工具,可以在移動端實現(xiàn)類似 PC 瀏覽器里的調(diào)試功能

2. 從大范圍到小范圍的 log

因為移動端無法 debugger,只能逐步的 log 去定位問題。我們采用的是 vue 技術(shù)棧,可以從 main.js 到路由組件的生命周期里去添加 log,通過這種方式定位到了在一個接口請求的方法之后的代碼都不會請求,奇怪的是也沒有拋出任何異常,并且在 vConsole 里的 network 下找到了該請求也是正常的響應(yīng),如下代碼:

try {
    console.log('start fetch')
    const res = await FetchXXX();
    console.log(res)
} catch (e) {
    console.log(e)
}

只打印出了start fetch,請求的結(jié)果和捕獲的異常里都沒有打印出東西,至此又縮小了排查的范圍,一定是請求的響應(yīng)處理部分出現(xiàn)問題了。

因為我們的請求接口方法是基于 axios 統(tǒng)一封裝的,本以為是封裝的哪個環(huán)節(jié)有不兼容頭條的代碼,通過不斷的 log,發(fā)現(xiàn) request interceptor 都執(zhí)行了,但是 response interctpor 一個都沒執(zhí)行,好家伙,看著不像我們封裝的問題,應(yīng)該是 axios 內(nèi)部處理的問題。

3. axios 源碼一覽

通過上面的一頓操作,基本可以確認(rèn)是 axios 內(nèi)部處理響應(yīng)數(shù)據(jù)時可能有部分兼容性問題,去 github 上去找 issue 也沒找到相關(guān)的問題。 沒辦法只能去看 axios 的源碼了,我們前面定位到是請求發(fā)送沒問題,在響應(yīng)的時候應(yīng)該是遇到了啥異常,并且還沒有拋出。

項目里 axios 用的版本是 0.24.0,我直接在 node_modules 里看 axios 的源碼,因為 npm 下載的 axios 包沒有用 webpack 或者 rollup 之類的編譯過,所以在 node_modules 里看和看源碼無異,并且更可靠(因為項目里是直接引用的這個代碼)。打開 axios 源碼目錄

axios 的源碼不算復(fù)雜,目錄光看命名基本也能猜到是干啥的,幾個主要目錄如下:

adapters:針對不同的宿主環(huán)境使用不同的請求 api,目前只有瀏覽器端和 nodejs 端,adapters 目錄下的 xhr.jshttp.js 分別對這兩種環(huán)境進(jìn)行了實現(xiàn)。

cancel:取消請求的相關(guān)源碼

coreaxios 的核心源碼

helpers:工具方法

排查角度 - interceptor

之前定位到所有的 response interceptor 都沒執(zhí)行,根據(jù)這個現(xiàn)象我先找到 interceptor 相關(guān)的代碼,在 core/Axios.js 里找到以下代碼:

// 請求攔截器列表
var requestInterceptorChain = [];
var synchronousRequestInterceptors = true;
// 遍歷所有的請求攔截器并放入到列表中
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
    if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {
        return;
    }
    synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;
    // 請求攔截器后進(jìn)先出(棧)
    requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);
});
// 響應(yīng)攔截器列表
var responseInterceptorChain = [];
// 遍歷所有的響應(yīng)攔截器并放入到列表中
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
    // 請求攔截器先進(jìn)先出(隊列)
    responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);
});
var promise;
if (!synchronousRequestInterceptors) {
    // axios執(zhí)行隊列,包含所有的請求攔截器、請求方法、響應(yīng)攔截器,并按順序排列
    // 這里的dispatchRequest就是實際的請求方法
    var chain = [dispatchRequest, undefined];
    // 將所有的請求攔截器放請求的前面
    Array.prototype.unshift.apply(chain, requestInterceptorChain);
    // 將所有的響應(yīng)攔截器放請求的后面
    chain = chain.concat(responseInterceptorChain);
    promise = Promise.resolve(config);
    // 依次執(zhí)行整個執(zhí)行隊列,直至隊列為空
    while (chain.length) {
        promise = promise.then(chain.shift(), chain.shift());
    }
    return promise;
}

以上代碼就是 axiosinterceptor 核心的處理,一開始懷疑是不是所有的響應(yīng)攔截器沒有被加入到執(zhí)行隊列中,log 后發(fā)現(xiàn)沒有問題,所有響應(yīng)攔截器都在隊列中。

排查角度 - xhr

上面排除了 interceptor 的問題,我又懷疑 axios 封裝的 xhr 在響應(yīng)的時候有啥兼容性問題,于是查看 adapters/xhr.js,并找到處理響應(yīng)相關(guān)的代碼:

// 省略了許多不必要的代碼
var request = new XMLHttpRequest();
function onloadend() {
    console.log('onloadend')
    // ...
}
if ('onloadend' in request) {
    console.log('use onloadend')
    request.onloadend = onloadend;
} else {
    console.log('use onreadystatechange')
    request.onreadystatechange = function handleLoad() {
        if (!request || request.readyState !== 4) {
            return;
        }
        setTimeout(onloadend);
    };
}

axios 處理響應(yīng)的代碼大致如上,如果瀏覽器 xhr 對象包含 onloadend 事件就監(jiān)聽 onloadend 事件,否則監(jiān)聽 onreadystatechange 來實現(xiàn)請求響應(yīng)的回調(diào),通過 log 我發(fā)現(xiàn)打印了use onreadystatechange,但是沒打印onloadend

至此終于找到問題所在,頭條 iOS 該版本的 xhr 對象雖然聲明了 onloadend 事件但是請求結(jié)束后并未回調(diào)該事件!

4. 解決問題

因為我們其他站點在頭條上是可以正常訪問的,我看了那些站點的代碼,發(fā)現(xiàn)他們用的 axios 版本是 0.18.1,看下 0.18.1 版本的 adapters/xhr.js 文件對于響應(yīng)的處理:

他是直接使用的 onreadystatechange 方法來監(jiān)聽的,所以沒有問題。

至此整個排查結(jié)束,最后通過降級 axios 版本解決該問題。

以上就是從axios源碼角度解決bug的過程記錄的詳細(xì)內(nèi)容,更多關(guān)于axios源碼角度bug解決的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • javascript-表格排序(降序/反序)實現(xiàn)介紹(附圖)

    javascript-表格排序(降序/反序)實現(xiàn)介紹(附圖)

    使用了Array方法、sort:降序、reverse:反序完成了基本功能,對于聯(lián)合排序沒有實現(xiàn),感興趣的朋友可以參考下哈
    2013-05-05
  • 淺析JavaScript中的類型和對象

    淺析JavaScript中的類型和對象

    這篇文章主要介紹了一些關(guān)于類型和對象的例子,大家看完例子后可能更容易理解類型和對象之間的聯(lián)系
    2013-11-11
  • 實現(xiàn)div滾動條默認(rèn)最底部以及默認(rèn)最右邊的示例代碼

    實現(xiàn)div滾動條默認(rèn)最底部以及默認(rèn)最右邊的示例代碼

    下面小編就為大家分享一篇實現(xiàn)div滾動條默認(rèn)最底部以及默認(rèn)最右邊的示例代碼,代碼非常簡潔,具有很好的參考價值,希望對大家有所幫助
    2017-11-11
  • 淺析IE10兼容性問題(frameset的cols屬性)

    淺析IE10兼容性問題(frameset的cols屬性)

    主頁用frameset嵌了兩個頁面,左側(cè)為菜單欄,可以通過改變 frameset的cols來收縮。別的瀏覽器正常,但I(xiàn)E10卻沒任何的反應(yīng)
    2014-01-01
  • 微信小程序授權(quán)登錄及解密unionId出錯的方法

    微信小程序授權(quán)登錄及解密unionId出錯的方法

    這篇文章主要介紹了微信小程序授權(quán)登錄及解密unionId出錯的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • 前端開發(fā)基礎(chǔ)javaScript的六大作用

    前端開發(fā)基礎(chǔ)javaScript的六大作用

    這篇文章主要介紹了前端開發(fā)基礎(chǔ)javaScript的六大作用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • js禁止瀏覽器的回退事件

    js禁止瀏覽器的回退事件

    這篇文章主要為大家詳細(xì)介紹了js禁止瀏覽器的回退事件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • JS實現(xiàn)進(jìn)入頁面時漸變背景色的方法

    JS實現(xiàn)進(jìn)入頁面時漸變背景色的方法

    這篇文章主要介紹了JS實現(xiàn)進(jìn)入頁面時漸變背景色的方法,涉及javascript操作css控制背景色漸變的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • 詳解CocosCreator消息分發(fā)機(jī)制

    詳解CocosCreator消息分發(fā)機(jī)制

    這篇文章主要介紹了詳解CocosCreator消息分發(fā)機(jī)制,詳細(xì)介紹了各模塊的設(shè)計,同學(xué)們一定要自己看下
    2021-04-04
  • 微信小程序中視頻的顯示與隱藏功能

    微信小程序中視頻的顯示與隱藏功能

    這篇文章主要介紹了微信小程序中視頻的顯示與隱藏,思路大概是定義一個標(biāo)記變量,控制視頻的播放與暫停,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-10-10

最新評論