Edited at

window.onerrorでエラー内容が取れない時の対応

More than 1 year has passed since last update.


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があがっていました。

https://github.com/jrburke/requirejs/issues/687

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;
};



crossorigin属性を追加

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でロードする場合にも対応出来ました。