我有一个脚本可以检测我网站上的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错误。 最大的罪犯之一是“剧本错误”。在Chrome 10+和Firefox 3+上的第0行。 Internet Explorer中不存在此错误(或可能称为其他内容?)。
更正(2013年5月23日):此“脚本错误,第0行”错误现在显示在IE7和可能的其他版本的IE中。可能是最近IE安全补丁的结果,因为此行为以前不存在。
有谁知道这个错误的含义或原因是什么?它发生在我的总页面加载量的大约0.25%上,并且代表报告错误的一半。
答案 0 :(得分:248)
“脚本错误”。当异常违反浏览器的same-origin policy时,即在当前页面的域以外的域上托管的脚本中发生错误时,会发生在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不支持onerror。)
从马口:WebKit source that checks origin将异常传递给onerror()时。还有Firefox source that checks。
更新(10/21/11):Firefox bug that tracks this issue包含启动此行为的博客帖子的链接。
更新(12/2/14):您现在可以在某些浏览器上启用完整的跨域错误报告,方法是在脚本标记上指定crossorigin
attribute并让服务器发送相应的CORS HTTP响应标头。
答案 1 :(得分:49)
将来会遇到这个问题的人的更新: 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/
答案 2 :(得分:23)
这个花了很多时间才弄明白。
我们做了很多事情来尝试解决它,包括通过Ajax将WHOLE文档体转储回我们的服务器来尝试解决它。
我仍然不确定导致“脚本错误”的原因。 (在BTW期间,这就是它在我们的Ajax记录器中的显示方式)在Firefox中,但在Chrome中,我们能够将其缩小到......
鼓声......
Google Chrome的自动翻译功能。
许多讲英语的人可能甚至不知道这个功能,但为了测试它,我想使用Chrome访问一个非英语网站。或者更好的是,如果您通过Chrome选项进行挖掘,则可以更改浏览器语言。将其更改为非英语,重新启动浏览器,然后访问英语网站。
你应该在顶部找到一个栏,询问你是否希望Chrome为你翻译页面。
在我们的案例中,无论如何,翻译器导致了这个问题,因为它在你的文档体中注入了一个脚本标签,并且(在这里猜测)使用某种基于JS的系统将内容发送到谷歌的服务器并让他们翻译它
即使控制台中的错误是Unreferenced something,发送到window.onerror的消息也是“Script Error。”。
无论如何,有一种治愈方法。
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中使用非英语模式写这个,并且拼写检查器未设置为英语;)时间切换回来。
享受!
答案 3 :(得分:11)
由于%较低,您可以假设他们不是普通用户。可能是用户使用用户脚本,书签,甚至可能只是搞乱你网站上的控制台。 拥有页面的整个HTML可以帮助测试这个理论。以及完整的错误。它应该给你一个网址,它总是一样吗?这条线真的是0还是刚刚未定义?
我不认为在你的错误中设置默认值是个好主意,如果页面上没有错误,0可能来自parseInt(ln || 0)
。(参见上面的例子)。
添加一个if以查看在JavaScript中是否已知该行以忽略这些错误(因为它们可能不是来自您自己的代码)或在服务器端代码中单独处理它们,imo ,更好。
===编辑=== 得到: http://www.xavierm02.net/AZE/ 安装user.js文件(我在Chrome上做过,但它也适用于Firefox)。 然后在同一浏览器上打开html页面。它会向您显示错误(我只更改了向服务器报告的内容,它将其写在页面上)。 0为行号。
答案 4 :(得分:3)
我遇到了类似的问题:我的脚本由子域服务,并且属于同一原点限制。但是,我通过以下方式解决了这个问题:
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&amp;字体,cdn是可用的,但是关于脚本标签的交叉原始细节却很少。
答案 5 :(得分:1)
在Chrome中,当从file://
加载HTML和Javascript时,我也会收到“脚本错误”(第0行)。这在Firefox中不会发生。可能过于热心的Chrome同源保护。
通过HTTP加载相同的HTML和Javascript时,一切都很好。
答案 6 :(得分: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;
};
答案 7 :(得分:1)
最后指向这个帖子的好文章。 https://danlimerick.wordpress.com/2014/01/18/how-to-catch-javascript-errors-with-window-onerror-even-on-chrome-and-firefox/
答案 8 :(得分:0)
我会告诉你在Safari(WebKit)上为我修复了什么: 如果我把JS回调例程实际上放在页面上的 ,那么我会得到完整的信息。如果我通过标签将它包含在.js文件中,我只会收到“脚本错误”错误(没有亚麻等)。
也许这与布罗法所说的有关。
Anwyay,现在我在页面中有一个小回调,然后是页面外的其余文件。
答案 9 :(得分:0)
iOS上的Chrome和Firefox都基于Safari Webview,但是在加载的每个页面中插入了一堆自定义脚本。如果在任何这些脚本中出了问题,则也会报告Script error on line 0
。 (浏览器插入的脚本也算作跨源)
正如我在this other SO thread中所跟踪和记录的那样,iOS上的Chrome和Firefox在自定义脚本中均存在正确处理SVG元素的问题。因此,除了该线程中的所有其他答案之外:如果您在页面上的<a>
标签内使用SVG元素和<svg>
标签,则会导致Script errors
在iOS Chrome和iOS中被报告Firefox。
答案 10 :(得分:-2)
我已经做了一些搜索,看起来“脚本错误”意味着它无法加载要求查找的文件。这可能是客户端的缓存问题,或者由于过载而可能是服务器问题。
最有可能的原因是脚本本身就是无法加载的文件,因此错误发生在第0行。
<script type="text/javascript" src="somescript.js"></script>
答案 11 :(得分:-3)
我经历过
脚本错误。第0行
在客户浏览器中发生错误时,错误会在一段时间内报告回我们的服务器。昨天是第一次(在我们的javascript中引入"use strict";
后)我能够在Windows 7上的Safari和Chrome中复制此问题。在使用alert()语句乱丢我们的代码后,我将此错误追溯到使用一个未定义的变量!例如xx = 123;
其中 xx 未使用var
语句定义。
Safari报告此为
ReferenceError:严格模式禁止隐式创建全局属性'xx'
Web Inspector中的,但是window.onerror函数正在检测
脚本错误。第0行
答案 12 :(得分:-10)
Grepping Firefox的源代码显示,没有"Script Error."
。因此,您网站上的某些脚本很可能会抛出这样一个未被捕获的错误:
throw new Error('Script Error.');
这个声明可能只在Firefox和Chrome中达成。
不知道为什么没有行号。也许有些eval()
问题?