Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away