使用withCredentials和客户端证书使用jQuery的CORS请求失败

我无法弄清楚为什么这个CORS请求无法返回数据。

我在后端使用Catalyst MVC,使用Firefox 24.0作为浏览器。 jQuery 1.9.1。 请注意以下事项:

  1. otherdomain.com需要客户端证书。
  2. 直接命中资源会返回预期的数据。 ( https://otherdomain.com/resource/1 )返回正确的数据。

我有一个测试请求的简单页面:

 function get_data() { console.log("running"); $.ajax({ url: "https://otherdomain.com/resource/1", dataType: 'json', type: 'GET', xhrFields: { 'withCredentials': true }, crossDomain: true }).success(function(data) { console.log(data) $('#output').html(data); }).error(function(xhr, status, error) { alert("error"); console.log(xhr); }); } $(document).ready(function() { get_data(); });   

这是我的请求标题:

 GET /resource/1 HTTP/1.1 Host: otherdomain.com User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0 Accept: application/json, text/javascript, */*; q=0.01 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate DNT: 1 Referer: https://mydomain.com/test.html Origin: https://mydomain.com Connection: keep-alive Pragma: no-cache Cache-Control: no-cache 

这是我的回复标题。 (来自firebug控制台的视图源的副本)我在我的催化剂调试输出上看到请求被提供为200 OK并且内容被发送。

 HTTP/1.1 200 OK Date: Mon, 28 Oct 2013 19:31:08 GMT Server: HTTP::Server::PSGI Vary: Content-Type Content-Length: 653 Content-Type: application/json Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Origin: * Access-Control-Max-Age: 1800 X-Catalyst: 5.90030 Via: 1.1 otherdomain.com 

并且从ajax调用抛出错误:

 readyState: 0 responseText: "" status: 0 statusText: "error" 

firebug将请求事件中的响应主体显示为空,尽管它是200 OK。

我认为在使用’withCredentials’时需要一个飞行前请求,但我没有看到通过firebug发送的OPTIONS。

此外,我可以看到我的请求没有添加Access-Control-Request-Header ,所以我没有从服务器返回任何Access-Control-Allow-Headers

现在,Catalyst的前端是Apache2,我在虚拟主机中使用proxypass将请求发送到localhost:8080上的catalyst。 我不确定这是否有任何影响,但认为这可能很重要。 它应该对浏览器透明。

谢谢你的帮助!

  1. GET请求不是预检的。 看这里
  2. 响应凭证请求时,服务器必须指定域,并且不能使用通配符。 (不得为Access-Control-Allow-Origin:*)。 看这里

我有类似的问题,在Chrome中一切正常,但我在Firefox中的所有跨域请求(以及IE的类似问题)得到405。 我尝试添加xhrFields和crossDomain标志。 我也在使用xhr.withCredentials = true来实际执行xhr.withCredentials = true 。 我确保我在服务后端有主机名匹配。 我使用Access-Control-Allow-Credentials标头。

可能有所不同的一件事……我只在Origin头存在时发送这些头,因为如果我没有得到Origin,我对Access-Control-Allow-Origin的唯一响应可能是*因为我不知道原点是什么。