我明白为什么以下代码片段在 Firefox 和 Chrome 中不起作用:我们正在向另一个域发出 AJAX 请求。
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.perdu.com", true);
xhr.addEventListener("load", function() { console.debug(xhr.responseText); }, false);
xhr.send(null);
但是为什么 Safari 会输出这个呢?这是页面的实际内容。我有 Safari 7.1。
<html><head><title>Vous Etes Perdu ?</title></head><body><h1>Perdu sur l'Internet ?</h1><h2>Pas de panique, on va vous aider</h2><strong><pre> * <----- vous êtes ici</pre></strong></body></html>
最佳答案
更新
事实证明,从服务器或文件系统加载时,Safari 的行为有所不同。
下面的原始答案使用 file:///
方案测试 CORS 功能。 Safari 允许用户绕过该方案上的 CORS。
正如 Jonathan Crowe 在 localhost
上指出的那样,使用 http://
方案,Safari 会阻止响应,与 Firefox 和 Chrome 相同。
所以这个没有错误。至于文件系统上的行为,我想我们可以称之为功能,或者便利(考虑快速本地测试)?
注意:此更新依赖于额外的简单测试来从 HTTP 服务器提供以下 HTML 代码段。没什么花哨的,Safari 的行为就和其他浏览器一样。
原始答案
我可以重现这个问题。这可能是 Safari 7.1 中的一个错误,以下是我发现的临时结论。
- 无法在 Safari 7.0.1 上重现(请参阅 Jonathan Crowe 的评论)。
- 两个主要区别:
- Safari 是唯一不设置
Origin
header 的浏览器。其他人将其设置为null
。 - Safari 和 Chrome 中的 WebKit 版本有所不同。
- Safari 是唯一不设置
- Apple tracking system 上没有与 CORS 相关的错误报告.
此外,此版本的 Safari 允许在 XMLHttpRequest
对象上设置 Origin
header (Chrome 不允许):
xhr.setRequestHeader("Origin", null);
将 header 设置为 null
以更接近其他浏览器不会改变结果:Safari 7.1 仍然允许响应到达请求者。
我无法确定这是 Safari 7.1 中的一个错误,但它现在似乎就是这样。
下面是一些详细信息。
测试页面和代码
<html>
<script>
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.perdu.com", true);
xhr.addEventListener("load", function() { console.debug(xhr.responseText); }, false);
xhr.send(null);
</script>
</html>
测试版本
- Safari 7.1 (9537.85.10.17.1)
- 火狐33.1
- Chrome 38.0.2125.122
(全部在 Mac OS X 10.9.5 上)
Firefox 请求转储
GET / HTTP/1.1
Host: www.perdu.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:33.0) Gecko/20100101 Firefox/33.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: null
Connection: keep-alive
Chrome 请求转储
GET / HTTP/1.1
Host: www.perdu.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36
Origin: null
Accept: */*
DNT: 1
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,fr;q=0.6,ja;q=0.4,pt;q=0.2
Safari 请求转储
GET / HTTP/1.1
Host: www.perdu.com
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10
Accept-Language: en-us
DNT: 1
Connection: keep-alive
注意
我目前正在一系列 Web API 浏览器上使用 CORS 测试边缘情况。如果错误得到确认,那么问题应该不大——只要 API 安全性足够严格(因为 CORS 不保护服务器)!
更新
我已询问 Apple 是否可以确认其 feedback网站。
关于javascript - CORS 请求与 Safari 一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26947291/