スクリプトエラーは一般的なエラーです。しかし、この種のエラーでは、完全なエラーメッセージやエラー スタックが利用できません。そのため、これらのエラーはトラブルシューティングが困難です。このトピックでは、その原因を分析し、解決策を提示するとともに、Application Real-Time Monitoring Service (ARMS) でこの種のエラーを無視する方法についても説明します。
スクリプトエラーの原因
スクリプトエラーは、クロスオリジンエラーとも呼ばれます。Web サイトがサードパーティのドメイン名でホストされているスクリプトをリクエストして実行すると、スクリプトエラーが発生することがあります。最も一般的なシナリオは、コンテンツデリバリーネットワーク (CDN) を使用して JavaScript (JS) リソースをホストする場合です。
理解を深めるために、次の HTML ページが http://test.com ドメイン名にデプロイされていると仮定します:
<!doctype html>
<html>
<head>
<title>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 は関数ではありません
}ページが読み込まれると、次のエラーがキャプチャされます:
"Script error.", "", 0, 0, undefined 実際には、これは JS のエラーではありません。セキュリティ上の理由から、ブラウザは他のオリジンにある JS ファイルがスローする特定のエラーを意図的に隠します。これにより、管理されていないサードパーティのスクリプトが機密情報を不用意にキャプチャするのを効果的に防げます。したがって、同一オリジンのスクリプトのみが特定のエラーメッセージをキャプチャでき、他のオリジンのスクリプトはエラーを検出できても、特定のエラーメッセージをキャプチャすることはできません。詳細については「」をご参照ください。
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;
}以下のセクションでは、スクリプトエラーを解決する方法について説明します。
解決策 1:オリジン間リソース共有の有効化
オリジンをまたいで JS エラーをキャプチャするには、次の手順を実行します。
crossorigin="anonymous"属性を追加します。<script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>この手順により、ブラウザはサードパーティのスクリプトを匿名で取得するようになります。これは、ブラウザがスクリプトをリクエストする際に、Cookie や HTTP 証明書などの潜在的なユーザーID情報をサーバーに送信しないことを意味します。
クロスオリジンの HTTP レスポンスヘッダーを追加します。たとえば、次のコマンドを実行します。
Access-Control-Allow-Origin: *または、次のコマンドを実行することもできます。
Access-Control-Allow-Origin: http://test.com説明デフォルトでは、ほとんどの主要な CDN に
Access-Control-Allow-Originヘッダーがあります。以下は Alibaba Cloud CDN の例です:$ curl --head https://retcode.alicdn.com/retcode/bl.js | grep -i "access-control-allow-origin" => access-control-allow-origin: *
上記 2 つの手順を実行すると、window.onerror ハンドラーでクロスオリジンエラーをキャプチャできます。上記の例で、ページを再度読み込むと、次のエラーがキャプチャされます:
=> "ReferenceError: bar is not defined", "http://another-domain.com/app.js", 2, 1, [Object Error]解決策 2: try catch コマンドの追加 (オプション)
オリジン間リソース共有を有効にすることが難しい場合は、try-catch 文を追加します。
上記の HTML ページに try-catch 文を追加します。次のコードに例を示します。
<!doctype html>
<html>
<head>
<title>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, undefinedtry-catch 文はコンソールログに完全なエラー情報を生成しますが、window.onerror ハンドラーはスクリプトエラーしか生成しません。try-catch 文でキャプチャされた例外は手動で報告できます。詳細については「SDK メソッド」をご参照ください。
__bl.error(error, pos);try-catch 文を使用して一部の例外をキャプチャすることはできますが、解決策 1 を使用することを推奨します。
ARMS でのスクリプトエラーの無視
スクリプトエラーは通常、サードパーティのドメイン名配下のスクリプトから発生します。スクリプトエラーがアプリケーションの実行に影響しない場合は、ARMS フロントエンドモニタリング SDK の ignore パラメーターを設定して、それらを無視できます。
ignore パラメーターを使用すると、指定した JS エラーの報告を無視できます。このパラメーターの値は、ignoreUrls、ignoreApis、ignoreErrors の 3 つのプロパティを含むオブジェクトです。次のコードは、このパラメーターのデフォルト値を示しています。
ignore: {
ignoreUrls: [],
ignoreApis: [],
ignoreErrors: []
},ignoreErrors プロパティを使用して、スクリプトエラーを無視します。ignoreErrors プロパティは、指定されたルールに準拠する JS エラーを無視するために使用します。このプロパティの値には、文字列 (String 型)、正規表現 (RegExp 型)、メソッド (Function 型)、またはこれら 3 つの型を含む配列を指定できます。次のコードは、スクリプトエラーを無視する方法の例を示しています。
__bl.setConfig({
ignore: {
ignoreErrors: /^Script error\.?$/
}
});