0

http://www4.example.com上的页面尝试与http://www6.example.com/建立 xhr 连接 浏览器发送带有此标头的 GET 请求:

Origin: http://www4.example.com

www6.example.com 服务器发回:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://www4.example.com
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/plain
Date: ...
Keep-Alive: timeout=5, max=100
Transfer-Encoding: Identity
Server: Apache/2.2.20 (Ubuntu)
Vary: Accept-Encoding
X-Powered-By: PHP/5.3.6-13ubuntu3.7

然而我得到:

XMLHttpRequest cannot load http://www6.example.com/myscript.php?xhr=1&t=1234333223. Origin http://www4.example.com is not allowed by Access-Control-Allow-Origin.

我的代码符合我对 CORS 标准的理解,并且适用于 Chrome、Firefox、Opera 等,所以我假设这是 Safari 5.1 的错误?我的问题是我需要做什么来解决它?

4

1 回答 1

1

经过大量的试验和错误,并观察网络流量,我想我可以自我回答。

Safari 的错误是它首先发送一个 OPTIONS 飞行前请求,即使它是一个 GET 请求。

为了增加一些额外的复杂性,它似乎只在第二次请求时发送。(我认为这是因为我的第二个请求发送了一个额外的自定义标头......但我实际上无法隔离它,所以我认为还有其他事情发生 - 也许缓存交互?)

发送Access-Control-Allow-Headers主响应并不能解决问题:它首先执行 OPTIONS 请求,所以永远不会那么远。

我所做的修复是把它放在 PHP 脚本的最顶部:

if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
    header("Access-Control-Allow-Origin: ".@$_SERVER['HTTP_ORIGIN']);
    header("Access-Control-Allow-Credentials: true");
    header("Access-Control-Allow-Headers: Last-Event-Id, Origin, X-Requested-With, Content-Type, Accept, Authorization");
    exit;
    }

发回“Access-Control-Allow-Headers:*”不起作用。您必须明确列出所需的标题。我做了简单的实验,看起来它们不区分大小写。

不需要发回“Access-Control-Allow-Methods: POST, GET, OPTIONS”。

顺便说一句,发送了 Cookie ,但发送基本的身份验证详细信息(尽管在那里明确列出了 Authorization 标头)。从这个版本的 WebKit (534.57.2) 开始,这可能是对 CORS 实现的故意限制,而不是错误。

于 2013-11-04T02:59:16.523 回答