web-dev-qa-db-ja.com

不可解な「スクリプトエラー」。 ChromeおよびFirefoxのJavascriptで報告

WebサイトでJavascriptエラーを検出し、レポートのためにバックエンドに送信するスクリプトがあります。最初に発生したエラー、想定される行番号、および時間を報告します。

Doctypeを含めるための編集:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" xmlns:fb="http://www.facebook.com/2008/fbml">

...

<script type="text/javascript">
//<![CDATA[
// for debugging javascript!
(function(window){
    window.onerror = function(msg, url, ln) {
        //transform errors
        if (typeof(msg) === 'object' && msg.srcElement && msg.target) {
            if(msg.srcElement == '[object HTMLScriptElement]' && msg.target == '[object HTMLScriptElement]'){
                msg = 'Error loading script';
            }else{
                msg = 'Event Error - target:' + msg.target + ' srcElement:' + msg.srcElement;
            }
        }

        msg = msg.toString();

        //ignore errors
        if(msg.indexOf("Location.toString") > -1){
            return;
        }
        if(msg.indexOf("Error loading script") > -1){
            return;
        }

        //report errors
        window.onerror = function(){};
        (new Image()).src = "/jserror.php?msg=" + encodeURIComponent(msg) + "&url=" + encodeURIComponent(url || document.location.toString().replace(/#.*$/, "")) + "&ln=" + parseInt(ln || 0) + "&r=" + (+new Date());
    };
})(window);
//]]>
</script>

このスクリプトのため、私は自分のサイトで発生しているjavascriptエラーを鋭く認識しています。 最大の犯罪者の1人は、0行目の「スクリプトエラー」です。 in Chrome 10+、およびFirefox 3+。このエラーは、Internet Explorerには存在しません(または別の名前で呼ばれている可能性があります)。

Correction(5/23/2013):この「スクリプトエラー、行0」エラーは、IE7および場合によってはIEの他のバージョンで表示されます。この動作は以前は存在しなかったため、おそらく最近のIEセキュリティパッチの結果である可能性があります。

このエラーが何を意味するのか、または何が原因であるのか誰にも分かりますか?全体のページロードの約0.25%で発生し、報告されたエラーの半分を表します。

196
Mike Sherov

「スクリプトエラー」。 Firefox、Safari、およびChromeで発生します。例外がブラウザの same-Origin policy に違反する場合-つまり、ドメイン以外のドメインでホストされているスクリプトでエラーが発生する場合現在のページ。

この動作は、スクリプトが外部ドメインに情報を漏洩するのを防ぐためのものです。これが必要な理由の例として、誤ってevilsite.comにアクセスし、<script src="yourbank.com/index.html">でページを提供することを想像してください。 (はい、スクリプトタグをJSではなくhtmlに向けています)。これによりスクリプトエラーが発生しますが、ログインしているかどうかを確認できるため、このエラーは興味深いものです。ログインしている場合、エラーは'Welcome Fred...' is undefinedである可能性がありますが、ログインしていない場合は'Please Login ...' is undefinedである可能性があります。それらの線に沿って何か。

Evilsite.comがトップ20ほどの銀行機関に対してこれを行う場合、彼らはどの銀行サイトを訪問するかについてかなり良い考えを持ち、はるかにターゲットを絞ったフィッシングページを提供できます。 (これはもちろん一例です。しかし、ブラウザがanyデータがドメインの境界を越えることを許可しない理由を示しています。)

Safari、Chrome、Firefoxの最新バージョンでこれをテストしました-それらはすべてこれを行います。 IE9では、x-Originの例外はsame-Originの例外と同じように扱われません。 (そしてOperaはonerrorをサポートしていません。)

馬の口から: OriginをチェックするWebKitソース onerror()に例外を渡すとき。 チェックするFirefoxソース

UPDATE(10/21/11)この問題を追跡するFirefoxのバグ には、影響を受けたブログ投稿へのリンクが含まれていますこの動作。

UPDATE(12/2/14):一部のブラウザーで crossorigin属性 スクリプトタグで、サーバーに適切な CORS HTTP応答ヘッダーを送信させる。

251
broofa

将来この質問に出くわす人のための更新:broofaは答えにぴったりであり、これに対する回避策はありません。

明らかに他の人がこの制限につまずき、修正を要求するいくつかのバグがFirefoxに提出されました: Bug 69301 およびWebKitに Bug 70574

良いニュースは、Firefox 13のリリースでFirefoxのバグが解決されたことです。これは、次のように使用します。

<script src="http://somremotesite.example/script.js" crossorigin>

crossorigincrossorigin=anonymousと同等であり、ブラウザに スクリプトのCORSフェッチを行う 資格情報を送信せずに指示します。

スクリプトは、要求元のドメインと一致するAccess-Control-Allow-Origin HTTPヘッダー値で送信されることを確認する必要があります。

Access-Control-Allow-Origin: http://myhomesite.example
Access-Control-Allow-Origin: *

それ以外の場合、ブラウザはスクリプトのロードをキャンセルします

Apacheの場合:

Header set Access-Control-Allow-Origin "*"

(および その他のWebサーバー のCORSの例を参照してください。)

PHPでスクリプトを送信する場合:

header('Access-Control-Allow-Origin', 'http://myhomesite.example');

これをテストしましたが、期待どおりに機能します。 script.jsからのすべてのエラーは、メッセージ、ファイル、および行の詳細とともにwindow.onerrorハンドラーによってキャッチされます。

WebKitのバグはまだ修正されていませんが、パッチが提案されています(同じソリューションを使用しています)。修正がすぐにリリースされることを願っています。

CORSについての詳細はこちら: http://enable-cors.org/

49
adig

これを理解するにはかなり時間がかかりました。

試して解決するために、Ajaxを介して完全なドキュメント本文をサーバーにダンプして、それを試して理解するなど、さまざまなことを行いました。

「スクリプトエラー」の原因はまだわかりません。 (BTW期間では、Ajaxロガーに表示されます)Firefoxでは、Chromeでは、...に絞り込むことができました。

ドラムロール...

Google Chromeの自動翻訳機能。

英語を話す人の多くはおそらくこの機能についても知らないでしょうが、それをテストするには、Chromeを使用して英語以外のサイトにアクセスすることをお勧めします。さらに良いことに、Chromeオプションを使って掘り下げた場合、ブラウザの言語を変更する場所があります。英語以外の言語に変更し、ブラウザを再起動して、英語のサイトにアクセスしてください。

Chromeでページを翻訳するかどうかを尋ねる上部のバーを取得する必要があります。

とにかく、翻訳者はドキュメント本文にスクリプトタグを挿入し、(ここで推測して)何らかの種類のJSベースのシステムを使用してコンテンツをGoogleのサーバーに送信し、翻訳させるため、翻訳者が問題を引き起こしていました。

コンソールのエラーは「参照されていないもの」でしたが、window.onerrorに送信されたメッセージは「スクリプトエラー」でした。

とにかく、治療法があります。

http://googlewebmastercentral.blogspot.com/2007/12/answering-more-popular-picks-meta-tags.html

<meta name="google" content="notranslate"/>

これは2つのことを行います(私たちが知る限り、おそらくそれ以上?):

a)Chromeで翻訳バーがポップアップしないようにします。

b)translate.google.comによるページの翻訳を無効にします。

とにかく私たちの状況では、これはこれらの「スクリプトエラー」の1トンを解決しました。私たちが経験していた問題。

この投稿のスペルミスをお許しください。私はまだChromeで英語以外のモードを使用していますが、スペルチェッカーは英語に設定されていません;)戻る時間です。

楽しい!

23
anonymous-one

%が低いため、通常のユーザーではないと想定できます。おそらく、ユーザースクリプト、ブックマークレット、あるいはたぶんあなたのウェブサイトのコンソールをいじるだけのユーザー。ページのHTML全体がその場所にあると、この理論のテストに役立ちます。完全なエラーと同様に。それはあなたにURLを与えるはずです、それは常に同じですか?行は本当に0ですか、それとも未定義ですか?

Onerrorにデフォルト値を設定するのは良い考えではないと思います。エラーが実際にページにない場合は、おそらく0はparseInt(ln || 0)に由来します(上記の例を参照)。

JavaScriptでこれらのエラーを無視する(おそらく自分のコードに由来しないため)か、サーバー側のコードでそれらを個別に処理するかのいずれかで行が既知であるかどうかを確認するifを追加すると、 。

=== EDIT === Got to: http://www.xavierm02.net/AZE/ user.jsファイルをインストールします(Chromeで実行しましたが、 Firefoxでも動作します)。次に、同じブラウザでHTMLページを開きます。エラーが表示されます(サーバーへのレポートのインスタレーションのみを変更し、ページに書き込みます)。行番号として0を使用します。

10
xavierm02

同様の問題がありました:私のスクリプトはサブドメインによって提供され、同じOriginの制限に該当します。しかし、私はこれを次の方法で解決しました。

1)次のようなすべてのスクリプトタグを追加します。

<script type="text/javascript" src="http://subdomain.mydomain.tld" crossorigin="*.mydomain.tld" />

2)すべてのvhost内に次を追加してApache httpd.confを変更します(mod_headersを有効にする必要があります)。

<IfModule mod_headers.c>
Header add Access-Control-Allow-Origin "*.mydomain.tld"
</IfModule>

お役に立てれば ...

編集

私のサーバーの1つで、交換することを除いてこれを機能させることができませんでした

*.mydomain.tld

沿って

*

拡張情報をフィッシングする可能性がある*の欠陥に注意してください。 CORS、same-Origin、img、fonts、cdnのドキュメントは利用可能ですが、スクリプトタグのクロスオリジンの詳細についてはごく少数しか利用できません。

3
spoutnik
1

以下はどうですか。スクリプトエラーはJavaScriptを介して利用できないため、その特定のケースを分離して、できる限り最善の方法で処理してください。

window.onerror = function (msg, url, lineNo, columnNo, error) {
    var string = msg.toLowerCase();
    var substring = "script error";
    if (string.indexOf(substring) > -1){
        alert('Script Error: See Browser Console for Detail');
    } else {
        alert(msg, url, lineNo, columnNo, error);
    }
  return false;
};
1
Ron Royston

Chromeでは、file://からHTMLとJavascriptの両方をロードするときに「スクリプトエラー」(0行目)も発生します。これはFirefoxでは発生しません。おそらく、Chromeの熱狂的な同起源保護。

HTTP経由で同じHTMLとJavascriptをロードする場合、すべてが適切です。

1
Myrne Stol

Safari(WebKit)で何が修正されたかを説明します。実際にJSコールバックルーチンページ上を配置すると、完全な情報が得られます。タグを使用して.jsファイルに含めると、「スクリプトエラー」エラー(行番号などがない)が発生します。

たぶんこれはBroofaが言ったことに関連している。

Anwyay、だから今私はページ内に小さなコールバックを持ち、それからページ外のファイルの残りを持っています。

0
kbern