67
63

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-11-27

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

67
63
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
67
63

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?