背景&問題
我們的網(wǎng)站每天都會安排進行功能檢查,對于關(guān)鍵性的頁面今野,還會進行全頁面的鏈接可用性掃描葡公。之前一直用的是Google瀏覽器上Check My Links
這個擴展插件,總體來說速度還是很快的条霜。
但是隨著我們網(wǎng)站的安全升級催什,對于它高頻觸發(fā)的請求,我們會進行攔截重定向到鎖定頁面宰睡。然而由于是重定向蒲凶,它識別不出來這個鏈接是否有問題,會被當成正巢鹉冢可用旋圆。
因此檢測結(jié)果已經(jīng)不能作為我們的測試依據(jù),有必要對它進行改造麸恍。
解決方案
嘗試直接改造Check My Links
插件(失敗方案)
實際業(yè)務中灵巧,我們服務端實際上是約定過特定ip+請求UA的白名單機制,而且這個插件項目是開源的抹沪,于是一開始便打算對這個插件進行適應的改造刻肄。
然而分析了它源碼、進行改造調(diào)試后發(fā)現(xiàn)融欧,它的核心方法里敏弃,實際上是忽略了XMLHTTPRequest
請求出錯的情況。而且谷歌瀏覽器上遵循的W3C要求噪馏,請求UA不讓修改的麦到。
改造為Firefox插件(應用方案)
Check My Links
里面用了很多chrome特有的Api,所以這一步我并沒有直接把它遷移到Firefox欠肾,而是二次改造Firefox上的Simple Link Checker
這個插件瓶颠,并結(jié)合我們自身的需求進行了更為深度的功能定制。
新功能點
- 定制請求頭
- 請求頻率控制
- 增加高頻訪問統(tǒng)計
- 增加失敗重試機制
- 大批量異步并發(fā)轉(zhuǎn)為同步
- 異常位置高亮報警
核心源碼
定制化請求頭參數(shù):
遷移到firefox也是因為這個關(guān)鍵性的參數(shù)
setRequestHeader
在chrome不被允許修改請求UA董济,而firefox的協(xié)議是可以的步清。
var XMLHttpTimeout, client = new XMLHttpRequest();
client.open('GET', url, true);
const brower_UA = navigator.userAgent;
const custom_UA = `${brower_UA} Test-Header-XXX`
client.setRequestHeader("user-agent", custom_UA);
client.send();
獲取當前頁面所有的鏈接:
var links = document.getElementsByTagName("a");
封裝異步檢測方法要门,并在for循環(huán)里同步處理:
function sendMessagePromise(url) {
return new Promise((resolve, reject) => {
chrome.runtime.sendMessage({
"action": "check",
"url": url,
}, function(response) {
resolve(response);
});
});
}
async function linkCheck() {
for (let i=0; i<filterLinks.length; i++){
const ele = filterLinks[i]
const url = ele.href;
await sendMessagePromise(url)
.then(response => {
doSomething(response)
}
}
}
失敗重試機制
在原來的chrome插件里虏肾,對于請求失敗的訪問廓啊,默認statusCode為0,雖然這是比較小概率的出現(xiàn)的封豪,但是這樣強制改寫結(jié)果為通過谴轮,肯定是不合理的。
因此我這里是增加了對XMLHttpRequest.onError
的異常捕獲吹埠,并封裝了可參數(shù)化調(diào)用的重試方法第步,默認5次還不成功會拋出錯誤。
function check(url, retryCount = 5) {
var XMLHttpTimeout, client = new XMLHttpRequest();
...
client.onerror = function(e) {
if (retryCount <= 0) {
resolve({
status: 400,
message: url,
});
}else {
check(url, --retryCount)
}
};
}
高亮顯示報錯元素
對于報錯的元素位置缘琅,之前工具只會是以紅色背景色展示,對于我們整體主色調(diào)本身就是紅色的網(wǎng)站來說翩隧,很不友好堆生,有時還找不到。
因此本次我們對于報錯的位置雷酪,結(jié)合CSS動畫淑仆,進行了閃動處理,幫助檢測人員快速定位到異常發(fā)生的位置哥力。
@keyframes fade {
from {
opacity:1.0;
}
50% {
opacity:0.4;
}
to {
opacity:1.0;
}
}@-webkit-keyframes fade {
from {
opacity:1.0;
}
50% {
opacity:0.4;
}
to {
opacity:1.0;
}
}
.Fail {
border-radius:2px;
border-color:#c0392b;
color:#fff!important;
background-color:#c0392b!important;
animation:fade 600ms infinite;
-webkit-animation:fade 600ms infinite;
}
結(jié)語
這個定制化插件蔗怠,現(xiàn)階段僅作為之前chrome的插件的替代升級工具。但長遠的看省骂,我們還可以結(jié)合業(yè)務做更多的擴展功能蟀淮,看后期的使用發(fā)展和需求吧。