window.onerrorについて
window.onerror = function (msg, file, line, column, err) {
/*
msg: error message
file: file path
line: row number
column: column number
err: error object
*/
alert(msg + file + ':' + line);
};
window.onerrorに関数を設定しておくと、処理中catchされてないエラー、つまりUncaughtErrorの情報をここで取得することが出来ます。
"Script error. line: 0"
window.onerror = function (msg, file, line, column, err) {
console.error(msg + file + ':' + line);
};
throw new Error('test');
この時、msgには"Uncaught Error test"が渡ることが期待されますが、何故か"Script error."が常に渡ってくる場合があります。コンソールのログには出力されますが、エラーログを送信するなどの処理を書いている場合、原因を特定できないため非常に困ります。
原因と対策
これはブラウザのSame-Origin Policyによるもので、別ドメインのjsファイルをロードした時に起こります。
解決するためにはCORSを適切に設定する必要があります
-
Access-Control-Allow-Originをヘッダに設定
サーバー側の設定でヘッダーに
Access-Control-Allow-Origin: [許可するURI]
を追加します。全てのアクセス元に対して許可する場合は
*
を指定します。 -
crossorigin属性を設定
クライアント側でscriptタグに以下のように
crossorigin
属性を追加します。<script type="text/javascript" src="hoge.js" crossorigin="anonymous"></script>
requirejsの対応
require.jsを利用してロードする場合、前述したような対応はとれません。
require.load
をoverrideする方法もありますが、あまり選びたくない方法です。
そこで調べていると既にissueがあがっていました。
require.createNode
をoverrideして属性を追加できるようにしてくれたようです。
require.createNode = function (config, moduleName, url) {
var node = config.xhtml ?
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
document.createElement('script');
node.type = config.scriptType || 'text/javascript';
node.charset = 'utf-8';
node.async = true;
return node;
};
require.createNode = function (config, moduleName, url) {
var node = config.xhtml ?
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
document.createElement('script');
node.type = config.scriptType || 'text/javascript';
node.charset = 'utf-8';
node.async = true;
node.setAttribute('crossorigin', 'anonymous');
return node;
};
これでrequirejsでロードする場合にも対応出来ました。