6

我在我的 webapp (//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js) 中使用 Google 托管的 jQuery 作为错误诊断的一部分,我有一个 window.onerror 处理程序,它可以捕获任何我没有在本地捕获错误并让服务器知道它们。

到目前为止一切都很好,但是......有时我会遇到这样的错误:

"脚本错误。","加载脚本时出错","意外令牌 <"

我的假设是 Google CDN 在这些情况下被阻止(无论出于何种原因)。我确实有 jQuery 的本地后备,我相当确定它运行良好,但我想找出返回的内容,以便我可以测试我的假设,并可能将其中一些用户列入 Google CDN 的白名单(如果是公司防火墙阻止它)。

但到目前为止,我还无法弄清楚如何检索返回的内容。如果是文件,则无法检索 SCRIPT 标记的 innerText,由于跨域策略等原因,无法执行 ajax 请求。

有没有人对这怎么可能有任何想法?

4

1 回答 1

12

根本不可能获取<script>标签引用的任何文件的内容。这是有充分理由的:这样做可以让你绕过 XHR 的同源策略。

考虑:

<script src="https://www.example.com/private/api/getAuthToken" id="s"></script>

如果您可以访问响应的文本,则可以执行以下操作:

var stolenAuthToken = $('#s').text();

这显然很糟糕。因此,您永远不能阅读<script>标签带来的内容。

您的特殊情况因最近引入的更改而变得复杂,其中跨域脚本中的错误不会向您的页面处理程序报告任何有用的信息onerror。(本质上,这样做是为了修补一个信息泄露安全漏洞,该漏洞允许恶意网站推断您是否登录到某些知名网站等。)

这意味着您无法从 CDN 托管的脚本中获得有关错误的有用信息,因此进行了另一项更改以允许将CORS用于 CDN(或其他非同源)服务器以选择允许通过完整的错误详细信息到onerror处理程序。

我们(Facebook)需要一种机制来禁用#363897window.onerror中实现的静音行为。我们的静态脚本资源在与主站点不同的域下的 CDN 上提供。因为这些域不同,我们与 x 域逻辑发生冲突,阻止我们收集有关浏览器错误的有用信息。

这个“特性”已经被广泛采用(在 Firefox 和 Webkit 浏览器中),以至于我们在生产中看到的大多数未捕获的异常现在都没有可操作的信息。

crossorigin属性(最初用于<img>)允许您指定应使用 CORS 规则加载资源。它已由 Mozilla、WebKitChrome实现。

<script src="http://example.com/xdomainrequest" crossorigin="anonymous"></script>

不幸的是,在我的测试中,我发现 Google CDN 不发送CORS 标头。

GET http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js HTTP/1.1
Host: ajax.googleapis.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://fiddle.jshell.net/josh3736/jm2JU/show/
Origin: http://fiddle.jshell.net
Pragma: no-cache
Cache-Control: no-cache

HTTP/1.1 200 OK
Vary: Accept-Encoding
Content-Type: text/javascript; charset=UTF-8
Last-Modified: Tue, 13 Nov 2012 19:53:02 GMT
Date: Wed, 02 Jan 2013 22:54:25 GMT
Expires: Thu, 02 Jan 2014 22:54:25 GMT
X-Content-Type-Options: nosniff
Server: sffe
Content-Length: 93637
X-XSS-Protection: 1; mode=block
Cache-Control: public, max-age=31536000
Age: 169036

...

请注意请求中存在Origin标头(指示 CORS 请求),以及Access-Control-Allow-Origin响应中不存在标头。因此,即使您放置了该crossorigin属性,CORS 检查也会失败,并且您的脚本将收到已清理的错误详细信息。

在 Google CDN 服务器上启用 CORS存在三年前的问题。我不会屏住呼吸。


tldr: 如果您想要有意义的错误消息,您必须自己托管所有 JavaScript,在同一来源上。

于 2013-01-04T22:07:56.990 回答