隐秘的"脚本错误".在Chrome和Firefox的Javascript中报告

Mik*_*rov 196 javascript error-handling firefox google-chrome

我有一个脚本可以检测我网站上的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">
Run Code Online (Sandbox Code Playgroud)

...

<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>
Run Code Online (Sandbox Code Playgroud)

由于这个脚本,我敏锐地意识到我的网站上发生的任何javascript错误.最大的罪犯之一是"剧本错误".在Chrome 10+和Firefox 3+的第0行.Internet Explorer中不存在此错误(或可能称为其他内容?).

更正(2013年5月23日):此"脚本错误,第0行"错误现在显示在IE7和可能的其他版本的IE中.可能是最近的IE安全补丁的结果,因为此行为以前不存在.

有谁知道这个错误意味着什么或是什么导致它?它发生在我的总页面加载量的大约0.25%上,并且代表报告错误的一半.

bro*_*ofa 252

"脚本错误".当异常违反浏览器的同源策略时(即当在当前页面的域以外的域上托管的脚本中发生错误时)会发生在Firefox,Safari和Chrome中.

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

如果evilsite.com为前20家左右的银行机构提供此服务,他们会非常了解您访问的银行网站,并且可以提供更具针对性的网上诱骗网页.(当然,这只是一个例子.但它说明了为什么浏览器不允许任何数据跨越域边界.)

我已经在Safari,Chrome和Firefox的最新版本中对此进行了测试 - 他们都是这样做的.IE9没有 - 它将x-origin异常视为与同源异常相同.(并且Opera不支持错误.)

来自马口:WebKit源,在将异常传递给onerror()时检查原点.和Firefox的源码检查.

更新(10/21/11):跟踪此问题Firefox错误包括一个启动此行为的博客帖子的链接.

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

  • 你会想到有人会有这样的感觉:"远程脚本抛出了由于同源策略而隐藏的错误",而不是让你想知道出了什么问题,呃?... (146认同)
  • 小更新.当通过file://加载页面并且脚本通过eval()运行时,它也会在本地发生.次要用例但仍然:) (6认同)
  • 经过一番调查后,我注意到如果用户安装了Safari扩展程序(可能与Firefox插件相同),并且注入了带有错误的JavaScript代码,也会出现"脚本错误". (6认同)
  • 谢谢你.我想稍微澄清一下.我看到我一直包含在页面中的脚本的详细错误消息.例如,如果我从谷歌的cdn中包含jQuery并使用它来操纵我页面上不存在的元素,我会得到一个指向谷歌的CDN的错误.你是说"剧本错误".正在发生,因为远程脚本抛出异常? (3认同)
  • @broofa这是否意味着如果我在我的域上托管jquery而不是使用谷歌的CDN,我会变得更好除外? (3认同)

adi*_*dig 49

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

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

好消息是,随着Firefox 13的发布,Firefox已经解决了这个问题.这就是你使用它的方法:

<script src="http://somremotesite.example/script.js" crossorigin>
Run Code Online (Sandbox Code Playgroud)

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

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

Access-Control-Allow-Origin: http://myhomesite.example
Access-Control-Allow-Origin: *
Run Code Online (Sandbox Code Playgroud)

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

对于Apache:

Header set Access-Control-Allow-Origin "*"
Run Code Online (Sandbox Code Playgroud)

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

如果您使用PHP发送脚本:

header('Access-Control-Allow-Origin', 'http://myhomesite.example');
Run Code Online (Sandbox Code Playgroud)

我测试了这个,它按预期工作.来自script.js的所有错误都将由window.onerror处理程序捕获,包含消息,文件和行详细信息.

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

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

  • 假设我们要监视mysite.com/index.php中的JS错误,其中包含来自外部方的JS文件(例如API提供商的服务器apiprovider.com/api.js); 在这种情况下,我们无法访问该服务器,因此我们无法添加"Access-Control-Allow-Origin"标头.有没有办法得到源自api.js的错误消息? (3认同)
  • 好总结:http://blog.errorception.com/2012/12/catching-cross-domain-js-errors.html (2认同)

ano*_*one 23

这个花了很多时间来弄明白.

我们做了一些尝试解决它的东西,包括通过Ajax将WHOLE文档体转储回我们的服务器来尝试解决它.

我仍然不确定导致"脚本错误"的原因.(在BTW期间,这就是它在我们的Ajax记录器中显示的方式)在Firefox中,但在Chrome中,我们能够将其缩小到......

击鼓...

Google Chrome的自动翻译功能.

许多讲英语的人可能甚至不知道这个功能,但为了测试它,我想使用Chrome访问一个非英语网站.或者更好的是,如果您通过Chrome选项进行挖掘,则可以更改浏览器语言.将其更改为非英语,重新启动浏览器,并访问英语站点.

你应该得到顶部的栏,询问你是否希望Chrome为你翻译页面.

在我们的案例中,无论如何,翻译器引起了问题,因为它向您的文档正文中注入了一个脚本标记,并且(在此猜测)使用某种基于JS的系统将内容发送到Google的服务器并让他们进行翻译.

即使控制台中的错误是Unreferenced something,发送到window.onerror的消息也是"Script Error.".

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

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

<meta name="google" content="notranslate"/>
Run Code Online (Sandbox Code Playgroud)

这将做2件事(据我们所知,可能更多?):

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

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

无论如何,在我们的情况下,这解决了这些"脚本错误"的问题.我们遇到的问题.

请原谅这篇文章中的拼写错误,我仍然在Chrome中使用非英语模式写这个,并且拼写检查器未设置为英语;)时间切换回来.

请享用!

  • 直接原因可能是翻译脚本是从不同的域然后是网页运行的,而"onerror"(至少在Firefox中)只是在这种情况下说"脚本错误". (3认同)

xav*_*m02 10

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

我不认为在你parseInt(ln || 0)的错误中设置默认值是一个好主意,0可能来自页面上没有真正的错误(参见上面的例子).

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

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