jquery – xmlHttp.getResponseHeader不适用于CORS

前端之家收集整理的这篇文章主要介绍了jquery – xmlHttp.getResponseHeader不适用于CORS前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在.NET 4上有一个asp.NET WCF。这个服务用于验证用户。我们提交一个用户名和密码,然后应该返回一个包含认证cookie的HTTP头。使用本地托管的测试页,这是正常工作。我现在正在尝试访问标题信息跨域。我已将测试页面安装在不同的机器上,并配置为调用WCF。呼叫正在工作,呼叫中的“数据”回复是正确的。但是,我无法使用以下任一方式访问头信息:
alert(xmlHttp.getAllResponseHeaders());

要么

alert(xmlHttp.getResponseHeader("Set-Cookie"));

在IE中使用调试器和Firefox的“Live HTTP Header”插件,我可以看到返回的头信息。

在我的全局ajax页面中,我设置了处理CORS的响应。

private void EnableCrossDomainAjaxCall()
{
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","*");


    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {

        HttpContext.Current.Response.AddHeader("Cache-Control","no-cache");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers","Content-Type,Accept");

        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age","1728000");
        HttpContext.Current.Response.End();
    }

}

这是我用来调用该服务的AJAX:

$("#btnLogin").click(function (e) {
            var geturl;
            geturl = $.ajax({
                // type: "POST",type: "GET",contentType: "application/json; charset=utf-8",url: 'http://10.0.4.66/AuthenticationService.svc/Login?Name=test&password=pwsd',// url: '../SecurityServer/AuthenticationService.svc/Login?Name=test&password=pwsd',dataType: "jsonp",error: function (request,status,error) {
                    alert('Error Occured');
                },crossdomain: true,success: function (data,textStatus,xmlHttp) {
                    // alert(xmlHttp.getResponseHeader("Content-Type"));
                    document.write(xmlHttp.getResponseHeader("Content-Type") + "<br/>");
                    alert(xmlHttp.getAllResponseHeaders());
                    alert(xmlHttp.getResponseHeader("Set-Cookie"));
                    var headers = '';
                    var headerPair = xmlHttp.getAllResponseHeaders('wcfCookie').split("\r\n");
                    var output = '';
                    $.each(headerPair,function (key,line) {
                        var parts = line.split(':');

                        if (parts[0] == 'wcfCookie') {
                            ChocChip = parts[1]
                            return false
                        }

                    });

                }

            });

以下是我的头信息从“Live HTTP头”

Date: Mon,04 Feb 2013 12:12:40 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
Access-Control-Allow-Origin: *
Set-Cookie: wcfCookie=8D38D5D6A0F138FEB595DD016F7694EDDF3E6757C82ED3D419F5047A5294974C1885487465CEC0A0BCC2B3802C7B03FF9F5370A05D4CCBDDDABCB1558C3816044BF4F78209BF38C6B1A7CAD34CD3C85C40B8515CFB1C2B2694BC78803D8DACB4
Content-Length: 65
Cache-Control: application/json; charset=utf-8
Content-Type: application/x-javascript

解决方法

首先,有一点背景:

您正在使用Access-Control-Allow-Headers,它指定客户端允许发送哪些请求头,但是您没有指定客户端可以读取哪些响应头。要允许客户端读取非简单的响应头,您需要使用Access-Control-Expose-Headers。从HTML5 Rocks CORS page

During a CORS request,the getResponseHeader() method can only access simple response headers. Simple response headers are defined as follows:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

If you want clients to be able to access other headers,you have to use the Access-Control-Expose-Headers header. The value of this header is a comma-delimited list of response headers you want to expose to the client.

所以,考虑到新的信息,你可能会这样做:

HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers","Set-Cookie");

…但是还有更多的。

现在,实际答案:

这里还有一个更严重的问题:XHR规范explictily disallows reading Set-Cookie.这是因为这在功能上是跨域Cookie窃取攻击。

假设域A对域B进行跨域请求。域B设置cookie时,只为域B设置域特定的cookie。域A读取域B的cookie的任何尝试都违反了Cookie访问的同源策略。

我不知道WCF,所以我不是确定最好的方式来实际做你想要的,但是我猜想解决方案可能是通过cookie传递auth令牌(例如,X-WCF-Auth标题?)域A读取然后设置自己的cookie。

猜你在找的jQuery相关文章