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

5
我不明白为什么这个CORS请求无法返回数据。
我在后端使用的是 Catalyst MVC,浏览器是 Firefox 24.0,jQuery 版本是 1.9.1。请注意以下几点:
1. otherdomain.com 需要客户端证书。 2. 直接访问资源可以返回期望的数据。(https://otherdomain.com/resource/1)可以返回正确的数据。
我有一个简单的页面来测试这个请求:
<script type='text/javascript'>
                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();
    });
    </script>

</script>

以下是我的请求头:

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控制台复制的视图源代码)。我在Catalyst调试输出中看到请求被作为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"

火狐调试工具显示请求的响应体为空,尽管它是200 OK。我认为使用'withCredentials'时需要预检请求,但我没有看到通过火狐发送OPTIONS请求。此外,我没有看到任何Access-Control-Request-Header被添加到我的请求中,因此我没有从服务器返回任何Access-Control-Allow-Headers。现在, Catalyst 的前端是 Apache2,我在虚拟主机中使用 proxypass 将请求发送到本地主机:8080 上的 Catalyst。我不确定这是否有任何影响,但我认为这可能很重要。但是对浏览器来说应该是透明的。感谢任何帮助!

对于遇到此问题的asp.net core用户,请使用以下代码:services.AddCors(); 然后在app.UseCors()中添加以下内容:options => { options.WithOrigins(" * 或者这里填写域名 ").AllowAnyMethod(); options.AllowCredentials(); } - Jay Dubal
2个回答

16
  1. GET请求不需要预检请求。请参见此处
  2. 响应带有凭据的请求时,服务器必须指定一个域名,不能使用通配符(不能是Access-Control-Allow-Origin: *)。请参见此处

1
我在程序的一个迭代中设置了 Access-Control-Allow-Origin: <origin>,但没有使用 Allow-Control-Allow-Credentials: true。当我添加 Allow-Credentials 时,我将其移回使用 * 作为 Origin。我不知道这个要求。非常感谢你的指导!现在可以工作了。 - mikew
10
请注意,GET 请求并非从不需要预检。如果请求包含自定义标头,则可能对 GET 请求进行预检。 - monsur
我认为 Allow-Control-Allow-Credentials 应该改为 Access-Control-Allow-Credentials(这为我解决了CORS错误,当我试图提供凭据时)。 - Radderz

0

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

可能不同的一件事是...只有在存在Origin头时,我才发送这些头,因为如果我没有Origin,我的Access-Control-Allow-Origin的唯一响应可能是*,因为我不知道来源是什么。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接