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

Posted

技术标签:

【中文标题】神秘的“脚本错误”。在 Chrome 和 Firefox 中以 Javascript 报告【英文标题】:Cryptic "Script Error." reported in Javascript in Chrome and Firefox 【发布时间】:2011-08-20 07:34:56 【问题描述】:

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

编辑以包含文档类型:

<!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 错误。 最大的罪魁祸首之一是“脚本错误”。在第 0 行。 在 Chrome 10+ 和 Firefox 3+ 中。 Internet Explorer 中不存在此错误(或者可能被称为其他错误?)。

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

有谁知道这个错误是什么意思或者是什么原因造成的?它发生在我整个页面加载的大约 0.25% 上,占报告错误的一半。

【问题讨论】:

您的文档类型是什么?如果您没有声明 XHTML 文档类型,那么您不需要 CDATA,这可能是出现脚本错误的原因。 感谢您的帮助...添加了文档类型:XHTML。而且,不过,只发生在 0.25% 的页面加载中……我认为这是更奇特的事情。 @jayp:只是提一下。 XHTML doctype 仍然是 HTML 解析器。您必须将内容发送为application/xhtml+xml 才能在 XHTML 解析器中运行它(就像 XHTML 规范所说的那样)。有很多内容声称是 XHTML,但发送的是普通的 HTML 文档类型。由于内容创建者使用 XHTML 的方式不正确,浏览器决定仅在 application/xhtml+xml 上使用 XML 解析器(它是非常严格的解析器)。 hixie.ch/advocacy/xhtml 和 webdevout.net/articles/beware-of-xhtml 说明了为什么不将 HTML 解析器与 XHTML 一起使用。 叹息...看在上帝的份上,任何阅读此内容的人,请让您的错误消息准确解释出了什么问题!通过为自己节省 30 秒的时间来编写它,你就是在浪费世界人年! 您忽略了错误加载脚本错误。为什么?可以安全地忽略它们吗? 【参考方案1】:

“脚本错误”。当异常违反浏览器的same-origin policy 时,Firefox、Safari 和 Chrome 会发生错误,即错误发生在托管在当前页面域以外的域上的脚本中。

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

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

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

从马口中:WebKit source that checks origin 将异常传递给 onerror() 时。还有Firefox source that checks。

更新(2011 年 10 月 21 日):Firefox bug that tracks this issue 包含一个指向激发此行为的博客文章的链接。

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

【讨论】:

谢谢。我想澄清一下。我一直在我的页面上看到来自脚本的详细错误消息。例如,如果我包含来自 google 的 cdn 的 jQuery 并使用它来操作页面上不存在的元素,我会收到一个指向 google 的 CDN 的 onerror。你是说“脚本错误”吗?正在发生,因为远程脚本正在抛出异常? 你会认为有人会说“远程脚本抛出了一个由于同源策略而被隐藏的错误”,而不是让你想知道出了什么问题,嗯?... @broofa 这是否意味着如果我在我的域上托管 jquery 而不是使用 Google 的 CDN,我会得到更好的异常? 小更新。当通过 file:// 加载页面并且脚本通过 eval() 运行时,它也会在本地发生。小用例但仍然:) 经过一番调查,我注意到Script Error. 如果用户安装了一个 Safari 扩展(可能与 Firefox 插件相同),它会注入错误的 JavaScript 代码【参考方案2】:

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

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

好消息是,随着 Firefox 13 的发布,Firefox 的错误已得到解决。 这就是你使用它的方式:

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

crossorigin 等价于crossorigin=anonymous 并告诉浏览器do a CORS fetch of the script 而不发送凭据。

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

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

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

对于 Apache:

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

(请参阅other web servers 的 CORS 示例。)

如果您使用 PHP 发送脚本:

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

我已经对此进行了测试,它可以按预期工作。 script.js 中的所有错误都将被window.onerror 处理程序捕获,其中包含消息、文件和行详细信息。

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

更多关于 CORS 的信息在这里:http://enable-cors.org/

【讨论】:

好总结:blog.errorception.com/2012/12/… 重新 webkit。如果你是说这个,现在看来已经解决了:bugs.webkit.org/show_bug.cgi?id=70574 假设我们要监控 mysite.com/index.php 中的 JS 错误,其中包括来自外部方的 JS 文件(例如 API 提供者的服务器 apiprovider.com/api.js);在这种情况下,我们无权访问该服务器,因此我们无法添加“Access-Control-Allow-Origin”标头。有什么方法可以获取来自 api.js 的错误消息?【参考方案3】:

这件事花了很多时间才弄清楚。

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

我仍然不确定导致“脚本错误”的原因。 (顺便说一句,这就是它在我们的 Ajax 记录器中的显示方式)在 Firefox 中,但在 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"/>

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

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

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

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

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

享受吧!

【讨论】:

直接原因可能是翻译脚本是从与网页不同的域运行的,onerror(至少在 Firefox 中)在这种情况下只会说“脚本错误”。 【参考方案4】:

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

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

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

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

【讨论】:

该 URL 均匀分布在我网站的页面中。考虑到它是 FF 和 chrome,我也在猜测小书签甚至扩展或主题。但是,我希望能够在安全地忽略它之前准确地重现此错误消息。 (new Image()).src = "/jserror.php?msg=" + encodeURIComponent(msg) + "&amp;url=" + encodeURIComponent(url) + "&amp;ln=" + parseInt(ln) + "&amp;r=" + (+new Date());替换你的行,你可能会看不到url(因为它是一个扩展或本地的东西,所以浏览器不会显示你)并且没有行号。 顺便说一句,您应该使用服务器而不是 JS 获取时间戳(甚至可能只是获取版本,而不是时间戳)。 事实上,JS 应该只发送原始数据,而 PHP 应该注意忽略加载错误等等。 我在 JS 端做了一些处理,因为我只想报告 FIRST 相关的错误,所以在真正的错误出现后,我将 onerror 函数重新分配回空。这也可以防止正在发生的错误在 ddos​​'ing 我的服务器的循环中。【参考方案5】:

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

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>

希望这会有所帮助...

编辑

在我的一台服务器上,除了替换之外,我无法使其正常工作

*.mydomain.tld

通过

*

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

【讨论】:

"*.mydomain.tld" 不是跨域属性developer.mozilla.org/en-US/docs/Web/HTML/…的有效值【参考方案6】:

一篇好文章终于指向了这个话题。 https://danlimerick.wordpress.com/2014/01/18/how-to-catch-javascript-errors-with-window-onerror-even-on-chrome-and-firefox/

【讨论】:

【参考方案7】:

在 Chrome 中,从 file:// 加载 HTML 和 Javascript 时,我也会收到“脚本错误”(第 0 行)。这在 Firefox 中不会发生。可能是对 Chrome 的过分热心的同源保护。

通过 HTTP 加载相同的 HTML 和 Javascript 时一切正常。

【讨论】:

【参考方案8】:

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

【讨论】:

你如何在 karma 上记录这个? 你是说浏览器控制台有详细信息,但 onerror 没有?【参考方案9】:

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

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

【讨论】:

【参考方案10】:

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

也许这与 Broofa 所说的有关。

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

【讨论】:

【参考方案11】:

我进行了一些搜索,似乎“脚本错误”意味着它无法加载要求查找的文件。这可能是客户端的缓存问题,也可能是由于过载导致的服务器问题。

这很可能是由于脚本本身是它无法加载的文件,因此错误发生在第 0 行。

<script type="text/javascript" src="somescript.js"></script>

【讨论】:

好主意,但是当脚本加载失败时我们会明确忽略。我们已专门检测到该错误并忽略它。 您是如何检测脚本加载失败的?我记得有一次遇到了麻烦。 script.onerror 不会因为某些浏览器中缺少脚本而被解雇。 “源错误。” (little-e) 出现在 webkit 和 FF 源中。见我上面的回答。 fwiw。【参考方案12】:

我经历过

脚本错误。第 0 行

当客户浏览器发生错误时,一段时间内的错误被报告回我们的服务器。昨天第一次(在我们的 javascript 中引入 "use strict"; 之后)我能够在 Windows 7 上的 Safari 和 Chrome 中复制这个问题。在使用 alert() 语句乱扔我们的代码后,我将此错误追溯到使用未定义的多变的!例如xx = 123; 其中 xx 未使用 var 语句定义。

Safari 将此报告为

ReferenceError:严格模式禁止隐式创建全局属性“xx”

在 Web Inspector 中,但正在检测 window.onerror 函数

脚本错误。第 0 行

【讨论】:

【参考方案13】:

查看 Firefox 的源代码发现没有 "Script Error."。因此,您网站上的某些脚本很可能会引发如下未捕获的错误:

throw new Error('Script Error.');

这种说法可能只在 Firefox 和 Chrome 中出现。

不知道为什么没有行号。也许有一些eval() 的问题?

【讨论】:

我试过完全按照你的建议扔这个。它不报告“脚本错误”。它报告“未捕获引发的异常:脚本错误。”。好主意。 也可能是用户安装的扩展程序之一导致错误。 没办法。如果您查看正确的文件,您会在整个网络上看到“脚本错误”。 呃,没有。它实际上是“脚本错误”。带有一个小“e”。这就是为什么我在源代码中没有找到它。

以上是关于神秘的“脚本错误”。在 Chrome 和 Firefox 中以 Javascript 报告的主要内容,如果未能解决你的问题,请参考以下文章

chrome 扩展中的“拒绝加载脚本”错误

Chrome 和 Firefox 浏览器可以访问微软更新目录网站啦!

Chrome 和 Firefox 浏览器可以访问微软更新目录网站啦!

Chrome 和 Firefox 浏览器可以访问微软更新目录网站啦!

浏览器兼容之layui分页组件

jQuery 开关类未在 Chrome 中正确激活