日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

“Script error.”的產生原因和解決辦法

“Script error.”是一個常見錯誤,但由于該錯誤不提供完整的報錯信息(錯誤堆棧),問題排查往往無從下手。本文提出了該錯誤的產生原因和解決辦法,以及在ARMS中忽略該錯誤的方法。

“Script error.”的產生原因

“Script error.”有時也被稱為跨域錯誤。當網站請求并執行一個托管在第三方域名下的腳本時,就可能遇到該錯誤。最常見的情形是使用CDN托管JS資源。

為了更好地理解,假設以下HTML頁面部署在http://test.com域名下:

<!doctype html>
<html>
<head>
  <title>Test page in http://test.com</title>
</head>
<body>
  <script src="http://another-domain.com/app.js"></script>
  <script>
  window.onerror = function (message, url, line, column, error) {
    console.log(message, url, line, column, error);
  }
  foo(); // 調用app.js中定義的foo方法。
  </script>
</body>
</html>

假設foo方法調用了一個未定義的bar方法:

// another-domain.com/app.js
function foo() {
  bar(); // ReferenceError: bar is not a function
}

頁面運行之后,捕獲到的異常信息如下:

"Script error.", "", 0, 0, undefined 

其實這并不是一個JavaScript Bug。出于安全考慮,瀏覽器會刻意隱藏其他域的JS文件拋出的具體錯誤信息,這樣做可以有效避免敏感信息無意中被不受控制的第三方腳本捕獲。因此,瀏覽器只允許同域下的腳本捕獲具體錯誤信息,而其他腳本只知道發生了一個錯誤,但無法獲知錯誤的具體內容。更多信息,請參見Webkit源碼

bool ScriptExecutionContext::sanitizeScriptError(String& errorMessage, int& lineNumber, String& sourceURL)
    {
        KURL targetURL = completeURL(sourceURL);
        if (securityOrigin()->canRequest(targetURL))
            return false;
        errorMessage = "Script error.";
        sourceURL = String();
        lineNumber = 0;
        return true;
    }

了解了 “Script error.”的產生原因之后,接下來看看如何解決這個問題。

解法1:開啟跨域資源共享CORS(Cross Origin Resource Sharing)

為了跨域捕獲JavaScript異常,可執行以下兩個步驟:

  1. 添加crossorigin="anonymous"屬性。

    <script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>

    此步驟的作用是告知瀏覽器以匿名方式獲取目標腳本。這意味著請求腳本時不會向服務端發送潛在的用戶身份信息(例如Cookies、HTTP證書等)。

  2. 添加跨域HTTP響應頭。

    Access-Control-Allow-Origin: * 

    或者

    Access-Control-Allow-Origin: http://test.com 
    說明 大部分主流CDN默認添加了Access-Control-Allow-Origin屬性。以下是阿里CDN的示例:
    $ curl --head https://retcode.alicdn.com/retcode/bl.js | grep -i "access-control-allow-origin"
    => access-control-allow-origin: *

完成上述兩步之后,即可通過window.onerror捕獲跨域腳本的報錯信息。回到之前的案例,頁面重新運行后,捕獲到的結果是:

=> "ReferenceError: bar is not defined", "http://another-domain.com/app.js", 2, 1, [Object Error]

(可選)解法2:try catch

難以在HTTP請求響應頭中添加跨域屬性時,還可以考慮try catch這個備選方案。

在之前的示例HTML頁面中加入try catch

<!doctype html>
<html>
<head>
  <title>Test page in http://test.com</title>
</head>
<body>
  <script src="http://another-domain.com/app.js"></script>
  <script>
  window.onerror = function (message, url, line, column, error) {
    console.log(message, url, line, column, error);
  }
  try {
    foo(); // 調用app.js中定義的foo方法
  } catch (e) {
    console.log(e);
    throw e;
  }
  </script>
</body>
</html>

再次運行,輸出結果如下:

=> ReferenceError: bar is not defined
     at foo (http://another-domain.com/app.js:2:3)
     at http://test.com/:15:3
=> "Script error.", "", 0, 0, undefined

可見try catch中的Console語句輸出了完整的信息,但window.onerror中只能捕獲“Script error”。根據這個特點,可以在catch語句中手動上報捕獲的異常,更多信息,請參見API參考

__bl.error(error, pos);
說明 盡管try catch方法可以捕獲部分異常,但推薦采用解法1。

如何在ARMS中忽略“Script error.”?

“Script error.”往往來源于第三域名下的腳本,如果不影響應用的運行,您可以選擇通過ARMS前端監控的SDK參數ignore忽略該錯誤。

ignore可忽略指定JS錯誤的上報,其配置項的值是一個對象,包含3個屬性:ignoreUrlsignoreApisignoreErrors。默認值如下:

ignore: {
    ignoreUrls: [],
    ignoreApis: [],
    ignoreErrors: []
},

針對“Script error.”,使用ignoreErrors即可。ignoreErrors表示忽略某些JS錯誤,符合該規則的JS錯誤不會上報。值可以是StringRegExpFunction或者以上三種類型組成的數組。示例:

__bl.setConfig({
    ignore: {
        ignoreErrors: /^Script error\.?$/
    }
});

相關鏈接