神秘的“脚本错误”。在 Chrome 和 Firefox 中用 JavaScript 报告

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5913978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:29:41  来源:igfitidea点击:

Cryptic "Script Error." reported in Javascript in Chrome and Firefox

javascriptfirefoxgoogle-chromeerror-handling

提问by Mike Sherov

I have a script that detects Javascript errors on my website and sends them to my backend for reporting. It reports the first error encountered, the supposed line number, and the time.

我有一个脚本可以检测我网站上的 Javascript 错误并将它们发送到我的后端进行报告。它报告遇到的第一个错误、假定的行号和时间。

EDIT to include 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>

Because of this script, I'm acutely aware of any javascript errors that are happening on my site. One of by biggest offenders is "Script Error." on line 0.in Chrome 10+, and Firefox 3+. This error doesn't exist (or may be called something else?) in Internet Explorer.

由于这个脚本,我非常清楚我的网站上发生的任何 javascript 错误。最大的罪犯之一是“脚本错误”。在第 0 行。在 Chrome 10+ 和 Firefox 3+ 中。Internet Explorer 中不存在此错误(或可能称为其他错误?)。

Correction (5/23/2013):This "Script Error, Line 0" error is now showing up in IE7 and possibly other versions of IE. Possibly a result of a recent IE security patch as this behavior previously did not exist.

更正 (5/23/2013):这个“脚本错误,第 0 行”错误现在出现在 IE7 和其他版本的 IE 中。可能是最近 IE 安全补丁的结果,因为此行为以前不存在。

Does anyone have any idea what this error means or what causes it? It happens on about 0.25% of my overall pageloads, and represents half the reported errors.

有谁知道这个错误是什么意思或导致它的原因是什么?它发生在我整个页面加载的 0.25% 左右,占报告错误的一半。

回答by broofa

The "Script error." happens in Firefox, Safari, and Chrome when an exception violates the browser's same-origin policy- i.e. when the error occurs in a script that's hosted on a domain other than the domain of the current page.

“脚本错误”。当异常违反浏览器的同源策略时,Firefox、Safari 和 Chrome 中会发生这种情况- 即当错误发生在托管在当前页面域以外的域上的脚本中时。

This behavior is intentional, to prevent scripts from leaking information to external domains. For an example of why this is necessary, imagine accidentally visiting evilsite.com, that serves up a page with <script src="yourbank.com/index.html">. (yes, we're pointing that script tag at html, not JS). This will result in a script error, but the error is interesting because it can tell us if you're logged in or not. If you're logged in, the error might be 'Welcome Fred...' is undefined, whereas if you're not it might be 'Please Login ...' is undefined. Something along those lines.

此行为是有意为之,以防止脚本将信息泄漏到外部域。举个例子说明为什么这是必要的,想象一下意外访问evilsite.com,它提供了一个带有 的页面<script src="yourbank.com/index.html">。(是的,我们将该脚本标记指向 html,而不是 JS)。这将导致脚本错误,但该错误很有趣,因为它可以告诉我们您是否已登录。如果您已登录,则错误可能是'Welcome Fred...' is undefined,而如果您未登录,则可能是'Please Login ...' is undefined。沿着这些路线的东西。

If evilsite.com does this for the top 20 or so bank institutions, they'd have a pretty good idea of which banking sites you visit, and could provide a much more targeted phishing page. (This is just one example, of course. But it illustrates why browsers shouldn't allow anydata to cross domain boundaries.)

如果 evilsite.com 为前 20 名左右的银行机构执行此操作,他们就会很清楚您访问哪些银行网站,并且可以提供更有针对性的网络钓鱼页面。(当然,这只是一个例子。但它说明了为什么浏览器不应该允许任何数据跨越域边界。)

I've tested this in the latest versions of Safari, Chrome, and Firefox - they all do this. IE9 does not - it treats x-origin exceptions the same as same-origin ones. (And Opera doesn't support onerror.)

我已经在最新版本的 Safari、Chrome 和 Firefox 中对此进行了测试 - 他们都这样做。IE9 没有——它把 x-origin 异常和同源异常一样处理。(而且 Opera 不支持 onerror。)

From the horses mouth: WebKit source that checks originwhen passing exceptions to onerror(). And the Firefox source that checks.

来自马口:在将异常传递给 onerror() 时检查来源的 WebKit 源。以及检查.

UPDATE (10/21/11): The Firefox bug that tracks this issueincludes a link to the blog post that inspired this behavior.

更新(2011 年 10 月 21 日)跟踪此问题Firefox 错误包含指向激发此行为的博客文章的链接。

UPDATE (12/2/14): You can now enable full cross-domain error reporting on some browsers by specifying a crossoriginattributeon script tags and having the server send the appropriate CORSHTTP response headers.

更新 (12/2/14):您现在可以通过在脚本标签上指定crossorigin属性并让服务器发送适当的CORSHTTP 响应标头,在某些浏览器上启用完整的跨域错误报告。

回答by adig

An update for those that will stumble into this question in the future : broofa is right with the answer and there's no workaround for this.

对于将来会遇到这个问题的人的更新:broofa 的答案是正确的,并且没有解决方法。

Obviously other stumbled into this limitation and some bugs requesting for an fix were filed for Firefox : Bug 69301and for WebKit : Bug 70574

显然,其他人偶然发现了这个限制,并且为 Firefox 提交了一些请求修复的错误Bug 69301和 WebKit:Bug 70574

The good news is that the bug has been resolved for Firefox with the release of Firefox 13. This is how you use it :

好消息是,随着 Firefox 13 的发布,Firefox 已经解决了该错误。 这是您使用它的方式:

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

crossoriginis equivalent to crossorigin=anonymousand tells the browser to do a CORS fetch of the scriptwithout sending credentials.

crossorigin相当于crossorigin=anonymous并告诉浏览器不发送凭据的情况下执行脚本的 CORS 提取

You must ensure that the script is sent with an Access-Control-Allow-OriginHTTP header value that matches the requesting domain, e.g.,

您必须确保使用Access-Control-Allow-Origin与请求域匹配的 HTTP 标头值发送脚本,例如,

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

otherwise the browser will cancel loading the script.

否则浏览器将取消加载脚本

For Apache:

对于阿帕奇:

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

(And see CORS examples for other web servers.)

(并参阅其他 Web 服务器的CORS 示例。)

If you're sending scripts in PHP:

如果您使用 PHP 发送脚本:

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

I've tested this and it works as expected. all errors from the script.js will be caught by the window.onerrorhandler with message, file and line details.

我已经测试过了,它按预期工作。来自 script.js 的所有错误都将被window.onerror处理程序捕获,包括消息、文件和行的详细信息。

The WebKit bug hasn't been fixed yet, but a patch has been proposed (and uses the same solution). Hopefully the fix will be released soon.

WebKit 错误尚未修复,但已提出补丁(并使用相同的解决方案)。希望修复程序将很快发布。

More info about CORS here : http://enable-cors.org/

有关 CORS 的更多信息,请访问:http: //enable-cors.org/

回答by anonymous-one

This one took quite a bit to figure out.

这个花了很多时间才弄明白。

We did a bunch of stuff to try and solve it, including doing things like dumping the WHOLE document body back to our servers via Ajax to try and figure it out.

我们做了很多事情来尝试解决它,包括通过 Ajax 将整个文档正文转储回我们的服务器以尝试解决它。

I am still unsure what causes "Script Error." (with the period BTW, that's how it shows up in our Ajax logger) in Firefox, but in Chrome, we were able to narrow it down to...

我仍然不确定是什么导致了“脚本错误”。(顺便说一句,这就是它在我们的 Ajax 记录器中的显示方式)在 Firefox 中,但在 Chrome 中,我们能够将其缩小到......

Drum roll...

击鼓...

The auto translate feature of Google Chrome.

谷歌浏览器的自动翻译功能。

Many English speaking people probably do not even know about this feature, but to test it, I guess visit a non-English site using Chrome. Or better yet, if you dig thru the Chrome options, there's a spot to change the browser language. Change it to something non-English, restart the browser, and visit an English site.

许多说英语的人可能甚至不知道这个功能,但为了测试它,我想访问一个使用 Chrome 的非英语网站。或者更好的是,如果您深入研究 Chrome 选项,则可以更改浏览器语言。将其更改为非英语内容,重新启动浏览器,然后访问英语站点。

You should get the bar at the top asking if you would like Chrome to translate the page for you.

您应该会看到顶部的栏,询问您是否希望 Chrome 为您翻译页面。

In our case anyways, the translator was causing the issue since it injects a script tag into your document body and (guessing here) uses some sort of JS-based system to send the content to Google's servers and get them to translate it.

无论如何,在我们的案例中,翻译器导致了问题,因为它将脚本标签注入到您的文档正文中,并且(在这里猜测)使用某种基于 JS 的系统将内容发送到 Google 的服务器并让他们翻译它。

Even though the error in the console was Unreferenced something, the message that was being sent to window.onerror was "Script Error.".

即使控制台中的错误是未引用的东西,发送到 window.onerror 的消息是“脚本错误。”。

Anyways, there is a cure.

无论如何,有一种治疗方法。

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

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

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

This will do 2 things (as far as we know, maybe more?):

这将做两件事(据我们所知,也许更多?):

a) Disable the translate bar from popping up in Chrome.

a) 禁止翻译栏在 Chrome 中弹出。

b) Disable translating of the the page via translate.google.com.

b) 通过 translate.google.com 禁用页面翻译。

In our situation anyways, this solved A TON of these "Script Error." issues we were experiencing.

无论如何,在我们的情况下,这解决了大量的“脚本错误”。我们遇到的问题。

Excuse the spelling mistakes in this post, I am still on a non-English mode in Chrome writing this, and the spell checker is not set to English ;) Time to switch back.

请原谅这篇文章中的拼写错误,我仍然在 Chrome 中使用非英语模式写这篇文章,而且拼写检查器没有设置为英语 ;) 是时候切换回来了。

Enjoy!

享受!

回答by xavierm02

Due to the low %, you can assume they're not normal users. Probably users with userscripts, bookmarklets or even maybe just messing with the console on you website. Having the whole HTML of a page where it happens could help testing this theory. As well as the complete error. It should give you a url, is it always the same? Is the line really 0 or just undefined?

由于百分比较低,您可以假设他们不是普通用户。可能是用户脚本,书签,甚至可能只是在您网站上弄乱控制台。拥有发生这种情况的页面的整个 HTML 有助于测试这一理论。以及完全错误。它应该给你一个网址,它总是一样的吗?该行是真的 0 还是只是未定义?

I don't think setting default values in you onerror is a good idea and the 0 probably comes from parseInt(ln || 0)when the error isn't really on the page (see examples above).

我认为在 onerror 中设置默认值不是一个好主意,并且 0 可能来自parseInt(ln || 0)错误不在页面上的情况(请参见上面的示例)。

Adding a if to see if the line is known either in the JavaScript to ignore those errors (because they probably don't come from your own code) or in the server-side code to take care of them separately would, imo, be better.

添加 if 以查看该行是否在 JavaScript 中已知以忽略这些错误(因为它们可能不是来自您自己的代码)或在服务器端代码中单独处理它们,imo 会更好.

=== EDIT === Got to: http://www.xavierm02.net/AZE/Install the user.js file (I did it on Chrome but it should work on Firefox too). Then open the html page on the same browser. It'll show you the error (I only changed that insteal of reporting to the server, it writes it on the page). With 0 as line number.

=== 编辑 === 到:http: //www.xavierm02.net/AZE/ 安装 user.js 文件(我在 Chrome 上做了,但它也应该在 Firefox 上工作)。然后在同一浏览器上打开 html 页面。它会向您显示错误(我只更改了向服务器报告的内容,它会将其写在页面上)。以 0 作为行号。

回答by spoutnik

I had a similar problem: my scripts are served by a subdomain and fall under the same origin restriction. However, I solved this by:

我有一个类似的问题:我的脚本由一个子域提供服务,并且属于同一来源限制。但是,我通过以下方式解决了这个问题:

1) adding every script tag like this:

1)像这样添加每个脚本标签:

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

2) modifying the apache httpd.conf by adding the following inside every vhost (you must enbable mod_headers):

2)通过在每个虚拟主机中添加以下内容来修改apache httpd.conf(您必须启用mod_headers):

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

Hope this helps ...

希望这可以帮助 ...

EDIT

编辑

On one of my server I was not able to make this functional except by replacing

在我的一台服务器上,除了更换

*.mydomain.tld

by

经过

*

Be aware of the flaws with potentially allowing * to phish extended information. Documentation on CORS, same-origin, img & fonts, cdn is available but very fewer about script tag crossorigin details is available.

请注意可能允许 * 网络钓鱼扩展信息的缺陷。有关 CORS、同源、img 和字体、cdn 的文档可用,但有关脚本标记跨域详细信息的可用文档很少。

回答by Myrne Stol

In Chrome, I also get "Script error" (on line 0) when loading both the HTML and Javascript from file://. This doesn't happen in Firefox. Probably overzealous same-origin protection of Chrome.

在 Chrome 中,从file://. 这在 Firefox 中不会发生。可能是过度热心的 Chrome 同源保护。

All is good when loading the same HTML and Javascript over HTTP.

通过 HTTP 加载相同的 HTML 和 Javascript 时,一切都很好。

回答by Ronnie Royston

How about the below. The script error is not available via JavaScript so just isolate that particular case and handle it as best you can.

下面怎么样。脚本错误无法通过 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;
};

回答by Laszlo Korte

Both Chrome and Firefox on iOS are based on the Safari Webview but insert a bunch of custom scripts into each page that is loaded. If in any of those scripts something goes wrong, it gets reported s Script error on line 0as well. (Browser inserted scripts count as cross origin as well)

iOS 上的 Chrome 和 Firefox 都基于 Safari Webview,但在加载的每个页面中插入了一堆自定义脚本。如果这些脚本中的任何一个出现问题,它Script error on line 0也会被报告。(浏览器插入的脚本也算作交叉原点)

As I have tracked down and documented in this other SO threadboth Chrome and Firefox on iOS have issues in their custom scripts handling SVG elements correctly. So in addition to all other answers in this thread: If you use SVG elements and <a>tags inside <svg>tags on your page, that will lead to Script errorsbeing reported in iOS Chrome and iOS Firefox.

正如我在另一个 SO 线程中追踪和记录的那样,iOS 上的 Chrome 和 Firefox 在其自定义脚本中正确处理 SVG 元素时存在问题。因此,除了此线程中的所有其他答案:如果您在页面上的<a>标签内使用 SVG 元素和标签<svg>,这将导致Script errors在 iOS Chrome 和 iOS Firefox 中被报告。

回答by kbern

I'll tell you what fixed it for me on Safari (WebKit): If I put the JS callback routine actually on the page, then I get full info. If I include it in a .js file via a tag, I just get the "Script error" error (with no linenumber, etc.).

我会告诉你在 Safari (WebKit) 上是什么修复了它:如果我将 JS 回调例程实际放在页面上,那么我会得到完整的信息。如果我通过标签将它包含在 .js 文件中,我只会收到“脚本错误”错误(没有行号等)。

Maybe this is related to what Broofa said.

或许这与布鲁法所说的有关。

Anwyay, so now I have a small callback in the page, and then the rest of the file outside of the page.

Anwyay,所以现在我在页面中有一个小的回调,然后是页面之外的文件的其余部分。