成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

一次排查頁(yè)面重復(fù)請(qǐng)求的經(jīng)歷

notebin / 3425人閱讀

摘要:前段時(shí)間重構(gòu)一個(gè)頁(yè)面,頁(yè)面中存在通過(guò)第三方代碼插入的動(dòng)態(tài)廣告正常的產(chǎn)品需求,上線后發(fā)現(xiàn)第三方的廣告資源存在重復(fù)請(qǐng)求的問(wèn)題。所以,同一個(gè)請(qǐng)求會(huì)觸發(fā)兩次的原因頁(yè)面加載時(shí)渲染元素會(huì)觸發(fā)第一次請(qǐng)求,執(zhí)行代碼導(dǎo)致重新渲染觸發(fā)第二次請(qǐng)求。

前段時(shí)間重構(gòu)一個(gè)頁(yè)面,頁(yè)面中存在通過(guò)第三方JavaScript代碼插入的動(dòng)態(tài)廣告(正常的產(chǎn)品需求),上線后發(fā)現(xiàn)第三方的廣告資源存在重復(fù)請(qǐng)求的問(wèn)題。由于控制廣告插入的JavaScript代碼由第三方提供,我們只負(fù)責(zé)按照他們要求的方式引入即可,所以對(duì)JavaScript代碼內(nèi)容并不了解,在這種情況下開(kāi)始了艱難的排查過(guò)程。雖困難重重,但最終還是找到了原因,在此過(guò)程中有些收獲,現(xiàn)將排查過(guò)程抽象如下:

注:以下過(guò)程和截圖皆在Chrome瀏覽器中進(jìn)行。

一、代碼

代碼大意:頁(yè)面上先渲染3個(gè)iframe(目前頁(yè)面插入廣告仍然以iframe作為主要實(shí)現(xiàn)形式),然后在最后一個(gè)iframe后面追加一個(gè)p元素

二、現(xiàn)象 1.頁(yè)面:渲染正常

2.Network:存在重復(fù)的異常請(qǐng)求(Status是canceled)

三、排查過(guò)程 1.重復(fù)請(qǐng)求從何而來(lái)?

既然是解決重復(fù)請(qǐng)求的問(wèn)題,那么重復(fù)請(qǐng)求從何而來(lái)是我們要解決的第一問(wèn)題。
由于請(qǐng)求是從第三方的JavaScript代碼中發(fā)出的,去讀第三方壓縮后的JavaScript代碼更像無(wú)頭蒼蠅。整個(gè)過(guò)程就像在圍城之外徘徊,心急如焚。后來(lái)靜下心來(lái)發(fā)現(xiàn)Chrome的devtools中一個(gè)很關(guān)鍵的排查助力神器:Network下的Initiator

此列是什么意思呢?通俗地說(shuō)就是觸發(fā)請(qǐng)求的位置。
通過(guò)對(duì)比發(fā)現(xiàn),同一個(gè)重復(fù)的請(qǐng)求發(fā)起的位置并不相同,以/iframe-1為例:
點(diǎn)擊第一個(gè)請(qǐng)求的Initiator,跳轉(zhuǎn)的位置(標(biāo)黃位置):

點(diǎn)擊第二個(gè)請(qǐng)求的Initiator,跳轉(zhuǎn)的位置(標(biāo)黃位置):

通過(guò)觀察可以發(fā)現(xiàn),第一個(gè)/iframe-1請(qǐng)求是由于正常渲染iframe元素自動(dòng)觸發(fā)的,第二個(gè)/iframe-1請(qǐng)求是在執(zhí)行JavaScript代碼(作用拼接DOM節(jié)點(diǎn))時(shí)觸發(fā)的,然而對(duì)于觸發(fā)第二個(gè)/iframe-1請(qǐng)求的那行JavaScript代碼,其真實(shí)意圖僅僅是拼接一個(gè)p元素而已,并不期望其他額外的事情(比如觸發(fā)新的請(qǐng)求)發(fā)生。另外,對(duì)于/iframe-2和/iframe-3的第二次請(qǐng)求的觸發(fā)點(diǎn)都是那段拼接DOM節(jié)點(diǎn)的JavaScript代碼,至此,產(chǎn)生問(wèn)題的罪魁禍?zhǔn)滓呀?jīng)浮出水面,接下來(lái)我們分析下產(chǎn)生重復(fù)請(qǐng)求的原因。

2.為什么會(huì)重復(fù)請(qǐng)求?

產(chǎn)生重復(fù)請(qǐng)求的JavaScript代碼

document.getElementById("container").innerHTML += "

上面是iframe

";

翻譯成:

document.getElementById("container").innerHTML = document.getElementById("container").innerHTML + "

上面是iframe

";

意思就明了多了:先獲取id為container的div元素的所有內(nèi)部HTML,將其拼接p元素后,再賦值給container的innerHTML。

這個(gè)過(guò)程會(huì)導(dǎo)致iframe元素的重新渲染,也就會(huì)引發(fā)iframe對(duì)應(yīng)的請(qǐng)求重新觸發(fā)。

所以,同一個(gè)請(qǐng)求會(huì)觸發(fā)兩次的原因:頁(yè)面加載時(shí)渲染iframe元素會(huì)觸發(fā)第一次請(qǐng)求,執(zhí)行JavaScript代碼導(dǎo)致iframe重新渲染觸發(fā)第二次請(qǐng)求。

找到了問(wèn)題的原因,解決問(wèn)題的辦法也就水到渠成了,將

document.getElementById("container").innerHTML += "

上面是iframe

";

改為:

var div = document.createElement("div");
var text = document.createTextNode("廣告");
div.appendChild(text);

document.getElementById("container").appendChild(div);

問(wèn)題解決了,不過(guò),還有一個(gè)疑問(wèn):為什么渲染iframe產(chǎn)生的第一個(gè)請(qǐng)求的狀態(tài)是canceled?

3.為什么重復(fù)的請(qǐng)求的Status是canceled?

首先Status是canceled代表什么意思呢?
從其字面意思理解,代表此請(qǐng)求被取消了,即此請(qǐng)求在發(fā)給服務(wù)器端之前就被瀏覽器取消了,也就是說(shuō)此請(qǐng)求根本就沒(méi)有從瀏覽器發(fā)出去,更不可能到達(dá)服務(wù)器,所以狀態(tài)是canceled而不是HTTP狀態(tài)碼也就不難理解了。

那第一次的請(qǐng)求為什么會(huì)被瀏覽器取消呢?
用關(guān)鍵詞“chrome cancel request”谷歌了一下,在stack overflow上找到了一個(gè)比較全面的解答,截圖如下:

其中紅色標(biāo)注即為我們要尋找的答案。

根據(jù)截圖大概梳理一下,Chrome瀏覽器會(huì)取消請(qǐng)求的幾種場(chǎng)景:

觸發(fā)請(qǐng)求的DOM元素被刪除了(比如img元素還沒(méi)有加載完就被刪除了)

做了一些不必要的數(shù)據(jù)加載(比如開(kāi)始加載iframe后改變其src或重寫(xiě)其內(nèi)容)

大量的請(qǐng)求指向同一個(gè)服務(wù)器,并且前面請(qǐng)求的網(wǎng)絡(luò)問(wèn)題表明后續(xù)的請(qǐng)求也走不通(DNS查詢(xún)錯(cuò)誤,前面的請(qǐng)求報(bào)400)

至此,整個(gè)過(guò)程中的疑問(wèn)點(diǎn)一一解開(kāi)了。

四、總結(jié)

現(xiàn)在再回顧此bug,產(chǎn)生的原因并不高深,但整個(gè)排查過(guò)程確實(shí)值得總結(jié)。小結(jié)一下:

1.對(duì)于第三方庫(kù)報(bào)錯(cuò),切莫妄圖通過(guò)通讀并熟悉整個(gè)庫(kù)后解決問(wèn)題,通讀代碼只會(huì)浪費(fèi)解決問(wèn)題的時(shí)間,弄明白調(diào)用關(guān)系才是王道

2.Chrome開(kāi)發(fā)者工具中的Network > Initiator代表請(qǐng)求是從哪里觸發(fā)的,對(duì)于定位請(qǐng)求非常有用,尤其是對(duì)于一些第三方庫(kù)中發(fā)出的請(qǐng)求

3.請(qǐng)求狀態(tài)為canceled,表示請(qǐng)求被瀏覽器取消了,并沒(méi)有從瀏覽器發(fā)出去,更不可能進(jìn)到服務(wù)器

4.Chrome瀏覽器取消請(qǐng)求的幾種情景,見(jiàn)上圖

5.element.innerHTML += HTMLStr 表示將原有的子節(jié)點(diǎn)和新的節(jié)點(diǎn)拼接后再重新賦值,會(huì)導(dǎo)致節(jié)點(diǎn)元素重新渲染,節(jié)點(diǎn)內(nèi)容中含有iframe時(shí)慎用

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/53125.html

相關(guān)文章

  • 一次排查頁(yè)面重復(fù)請(qǐng)求經(jīng)歷

    摘要:前段時(shí)間重構(gòu)一個(gè)頁(yè)面,頁(yè)面中存在通過(guò)第三方代碼插入的動(dòng)態(tài)廣告正常的產(chǎn)品需求,上線后發(fā)現(xiàn)第三方的廣告資源存在重復(fù)請(qǐng)求的問(wèn)題。所以,同一個(gè)請(qǐng)求會(huì)觸發(fā)兩次的原因頁(yè)面加載時(shí)渲染元素會(huì)觸發(fā)第一次請(qǐng)求,執(zhí)行代碼導(dǎo)致重新渲染觸發(fā)第二次請(qǐng)求。 前段時(shí)間重構(gòu)一個(gè)頁(yè)面,頁(yè)面中存在通過(guò)第三方JavaScript代碼插入的動(dòng)態(tài)廣告(正常的產(chǎn)品需求),上線后發(fā)現(xiàn)第三方的廣告資源存在重復(fù)請(qǐng)求的問(wèn)題。由于控制廣告插...

    hightopo 評(píng)論0 收藏0
  • 如果連鐵將軍都不再可靠--記一次排查使用分布式輪候鎖+SESSION防訂單重復(fù)仍然加鎖失效問(wèn)題經(jīng)歷

    摘要:盡可能地將數(shù)據(jù)寫(xiě)入,例如創(chuàng)建設(shè)置的都會(huì)將數(shù)據(jù)立即的寫(xiě)入再來(lái)看看文檔怎么描述的看看這可愛(ài)的默認(rèn)值我們終于知道了當(dāng)我們不做任何設(shè)置時(shí),默認(rèn)采用的是方式顯而易見(jiàn),使用方式能最大限度的減少與的交互,而在大多數(shù)場(chǎng)景下都是沒(méi)有問(wèn)題的。 0.問(wèn)題背景 此次問(wèn)題源于一次挺嚴(yán)重的生產(chǎn)事故:客戶(hù)的訂單被重復(fù)生成了,而出問(wèn)題的代碼其實(shí)很簡(jiǎn)單: // .... redisLockUtil.lock(membe...

    econi 評(píng)論0 收藏0
  • 一次 Laravel 應(yīng)用性能調(diào)優(yōu)經(jīng)歷

    摘要:為了一探究竟,于是開(kāi)啟了這次應(yīng)用性能調(diào)優(yōu)之旅。使用即時(shí)編譯器和都能輕輕松松的讓你的應(yīng)用程序在不用做任何修改的情況下,直接提高或者更高的性能。 這是一份事后的總結(jié)。在經(jīng)歷了調(diào)優(yōu)過(guò)程踩的很多坑之后,我們最終完善并實(shí)施了初步的性能測(cè)試方案,通過(guò)真實(shí)的測(cè)試數(shù)據(jù)歸納出了 Laravel 開(kāi)發(fā)過(guò)程中的一些實(shí)踐技巧。 0x00 源起 最近有同事反饋 Laravel 寫(xiě)的應(yīng)用程序響應(yīng)有點(diǎn)慢、20幾個(gè)并...

    warkiz 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<