我在我的webapp (//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js)中使用Google托管的jQuery作为bug诊断的一部分,我有一个窗口。onerror处理程序捕获任何错误,我没有捕捉到本地,并让服务器知道他们。
到目前为止还好,但是……有时我得到这样的错误:"脚本错误","加载脚本错误","意外的令牌<"
我的假设是谷歌CDN在这些情况下被阻止(无论出于什么原因)。我确实有一个jQuery的本地回退,我很确定工作得很好,但我想知道什么被返回,这样我就可以测试我的假设,也许得到一些这些用户在谷歌CDN白名单上(如果它的公司防火墙阻止它)。
但是到目前为止,我还没能弄清楚如何检索返回的内容。不能检索innerText的SCRIPT标签,如果它是一个文件,不能做一个ajax请求,因为跨域策略,等等
有人知道这是怎么可能的吗?
根本不可能获得<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)需要一个机制来禁用#363897中实现的
window.onerror
静音行为。我们的静态脚本资源在与主站点不同的域下的CDN上提供服务。因为这些域不同,所以我们与x域逻辑发生冲突,从而阻止我们收集有关浏览器错误的有用信息。这"feature"已经被广泛采用(在Firefox和Webkit浏览器中),我们在生产环境中看到的大多数未捕获异常现在都没有可操作的信息。
crossorigin
属性(最初用于<img>
)允许您指定应该用CORS规则加载资源。它已被Mozilla, WebKit和Chrome实现。
<script src="http://example.com/xdomainrequest" crossorigin="anonymous"></script>
不幸的是,在我的测试中,我发现谷歌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,在同一个源