Script error之全面解析
一些使用者向我們反饋,Fundebug的JavaScript監控外掛抓到了很多Script error.,然後行號和列號都是0…這就很尷尬了。
今天,我們來詳細地解析一下Script error.
,後續我們還會深度測試並且提供解決方法。
同源策略 (Same origin policy)
解釋Script error.
之前,我們先簡單聊聊同源策略。摘自MDN - Same-origin policy:
Two pages have the same origin if the protocol, port (if one is specified), and host are the same for both pages.
所謂同源,就是指兩個頁面具有相同的協議、埠和主機(域名)。通過第三方載入的JavaScript指令碼是不同源的。下面的表格簡單列出了和https://fundebug.com/app.js
是否同源的檔案:
網址 | 是否同源 | 原因 |
---|---|---|
https://fundebug.com/vendor.js |
是 | |
http://fundebug.com/vendor.js |
否 | 協議不同 |
https://fundebug.com:8001/app.js |
否 | 埠不同 |
https://docs.fundebug.com/nav.js |
否 | 子域名不同 |
https://kiwenlau.com/totop.js |
否 | 域名不同 |
沒有同源策略的話,將會怎樣?摘自同源策略詳解及繞過 - FreeBuf:
假設你已經成功登入Gmail伺服器,同時在同一個瀏覽器訪問惡意站點(另一個瀏覽器選項卡)。沒有同源策略,攻擊者可以通過JavaScript獲取你的郵件以及其他敏感資訊,比如說閱讀你的私密郵件,傳送虛假郵件,看你的聊天記錄等等。 如果將Gmail替換為你的銀行帳戶,問題就大條了。
為啥出現Script error. ?
為了提升網站的訪問速度,我們通常都會將靜態資原始檔(css, image, javascript)放在第三方CDN。當這些從第三方載入的JavaScript指令碼執行出錯,因為違背了同源策略, 為了保證使用者資訊不被洩露,錯誤資訊不會顯示出來,取而代之只會返回一個Script error.
。
暴露錯誤資訊會怎樣呢?摘自(Cryptic “Script Error.” reported in Javascript in Chrome and Firefox):
假想你不小心訪問了一個惡意網站,網頁裡面偷偷放入了一段JavaScript指令碼
<script src="cbcc.com/index.html">
,這段指令碼指向你使用的某銀行網站首頁。雖然指令碼會執行失敗,但是錯誤資訊卻有可能洩露你的資訊。如果你已經登入過該銀行網站並且處於登入狀態,那麼錯誤資訊可能為'歡迎你 ....' is undefined
;如果你沒有登入,那麼錯誤資訊可能是'請登入...' is undefined
。 然後黑客就可以根據這些資訊確定你使用的銀行網站,並且偽造一個釣魚網站來騙取錢財。
原始碼
webkit原始碼如下:
bool ScriptExecutionContext::dispatchErrorEvent(const String& errorMessage,
int lineNumber,
const String& sourceURL)
{
EventTarget* target = errorEventTarget();
if (!target)
return false;
...
if (securityOrigin()->canRequest(targetUrl)) {
message = errorMessage;
line = lineNumber;
sourceName = sourceURL;
} else {
message = "Script error.";
sourceName = String();
line = 0;
}
...
}
可知,瀏覽器會判斷所載入的資源url是否同源(securityOrigin()->canRequest(targetUrl)
),如果不同源,則將錯誤訊息隱藏,賦值為Script error.
, 並且將行號設為0.
因此,如果我們從第三方CDN服務載入資源,如果出錯的話,那麼我們將只能看到Script error.
。
錯誤復現
我們用一個簡單的例子測試一下。下面是index.html,我們使用onerror來捕獲錯誤。
<!DOCTYPE html>
<html>
<head>
<title>Test Script error</title>
<script type="text/javascript">
window.onerror = function(errorMessage, scriptURI, lineNumber, columnNumber, error){
console.log(errorMessage);
console.log(scriptURI);
console.log(lineNumber);
console.log(columnNumber);
console.log(error);
}
</script>
<script type="text/javascript" src="./scripterror.js"></script>
</head>
<body>
</body>
</html>
在scripterror.js中丟擲一個Error物件:
throw new Error('Hello, Fundebug');
使用的http-server
掛載檔案,開啟http://localhost:8080/index.html,
在Chrome瀏覽器控制檯下,可以看到詳細的出錯資訊:
為了復現Scrpt error.
, 將scripterror.js
放到我在coding.net
的個人專案下面:
<!DOCTYPE html>
<html>
<head>
<title>Test Script error</title>
<script type="text/javascript">
window.onerror = function(errorMessage, scriptURI, lineNumber, columnNumber, error){
console.log(errorMessage);
console.log(scriptURI);
console.log(lineNumber);
console.log(columnNumber);
console.log(error);
}
</script>
<script type="text/javascript" src="http://coding.net/u/stefanzan/p/stefanzan/git/raw/coding-pages/public/js/src/scripterror.js"></script>
</head>
<body>
</body>
</html>
執行http-server
, 結果如下:
因為違背同源策略,這時只能拿到Script error.
。
總結
本文介紹了Script error.
的由來,並提供了一個簡單的例項來演示什麼情況下出現Script error.
。接下來,我們將對Script error進行深度測試並提出解決方法
關於Fundebug
Fundebug專注於JavaScript、微信小程式、微信小遊戲、支付寶小程式、React Native、Node.js和Java實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了7億+錯誤事件,得到了Google、360、金山軟體、百姓網等眾多知名使用者的認可。歡迎免費試用!
版權宣告
轉載時請註明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/04/05/understand-script-error/