即使响应包含 ajax 请求的“Set-Cookie”标头,cookie 也不会存储在浏览器中

Posted

技术标签:

【中文标题】即使响应包含 ajax 请求的“Set-Cookie”标头,cookie 也不会存储在浏览器中【英文标题】:cookie not stored on browser even if response contains 'Set-Cookie' header for ajax request 【发布时间】:2018-11-16 09:00:07 【问题描述】:

请求代码:

function hitLogin()
        var loginUrl = "http://myapp:8080/login";

        var geturl;
        $.ajax(

            type: "GET",
            url : loginUrl,
            data:   
            user : "user1",
            password : "encryptedPassword"              
            ,              
            headers: 
                "credentials": 'include',
                "withCredentials" : true,
                "crossDomain": true,
                "X-Requested-With" : "XMLHttpRequest",
                "Content-type" : "application/x-www-form-urlencoded",
                "Accept":"text/plain",
            ,              

            success : function(data)
                               
                alert("Ajax request data: "+data);
            ,
            error: function( xhr, status, error ) 
            
                alert("Ajax request error: "+status ); 
            
        ); 
        

收到的响应标头:

访问控制允许凭据:true

Access-Control-Allow-Headers:X-Requested-With,accept,content-type,Cookie

访问控制允许方法:POST、GET、PUT、OPTIONS、DELETE

访问控制允许来源:http://myapp2.com:7011

访问控制最大年龄:3600

内容编码:gzip

Content-Type:text/plain;charset=ISO-8859-1

日期:格林威治标准时间 2018 年 6 月 6 日星期三 15:10:09

服务器:Apache-Coyote/1.1

设置-Cookie:MYCOOKIE=62lml5_S7qS31KaFDg-SH-e8Ds5FPjljCIHzfmhxMAr8Fdrqr6fHLjI7s2XPAO2P3tNFLNLS1_fgvDXF4pLmfg#1s1S1#normal-false; 路径=/; HttpOnly

传输编码:分块

变化:接受编码

withCredentials:true

当浏览器访问相同的 url 时,我可以看到存储在浏览器中的 cookie,但在 ajax 请求的情况下,它不会存储。 因此无法发送除此 cookie 之外的后续请求。

【问题讨论】:

【参考方案1】:

如前所述,这是 CORS 的情况,因此 jquery 请求无法设置 cookie。

Set-Cookie on Browser with Ajax Request via CORS

帮助找到原因并能够使用 XMLHttpRequest 存储 cookie,其中 withCredentials 设置为 true

【讨论】:

【参考方案2】:

您将 withCredentials: true 作为 HTTP 标头发送,这没有任何用处。您应该将其设置为XHR field。在 jQuery 中,你可以这样做:

$.ajax(
    type: "GET",
    url: loginUrl,
    data:  /* request parameters here */ ,
    headers:  /* custom HTTP headers here, if you need any */ ,
    xhrFields: 
        withCredentials: true,
    ,
    /* other AJAX settings here */
)

此外,您发送的所有其他自定义 HTTP 标头实际上也是无用的:

credentials: include 既不是有效的 HTTP 标头、XHR 字段也不是jQuery AJAX setting。相反,它似乎是 jQuery 的 withCredentials: true 的 Fetch API 等价物。反正在这里也没用。

crossDomain 也不是 HTTP 标头。它可以用作 jQuery AJAX 设置(即 headers 对象之外)以强制 jQuery 将请求视为跨域,即使目标 URL 看起来匹配当前页面的域。在你的情况下,它也没有用。

X-Requested-With: XMLHttpRequest HTTP 标头由 jQuery 自动添加,因此将其指定为自定义标头是 100% 多余的。

无需显式发送 HTTP Content-Type 标头,因为 jQuery 会自动生成一个。如果您希望指定 jQuery 应该为请求使用哪种内容类型,您应该使用 contentType 设置 outside headers 来做到这一点。在任何情况下,您指定的都是默认值。

1234563通常您不需要这样做,因为 jQuery 使用的默认值很好,除非您的服务器配置错误并发送错误的内容类型。

【讨论】:

Yes.some 标头可能没有用,但我主要担心的是 cookie 未存储在浏览器上。我们需要任何明确的处理/标题吗? @AmM:不,应该只需要withCredentials: true XHR 字段。它必须在正确的位置,即xhrFields,而不是headers

以上是关于即使响应包含 ajax 请求的“Set-Cookie”标头,cookie 也不会存储在浏览器中的主要内容,如果未能解决你的问题,请参考以下文章

即使我通过另一个模型,Ajax.BeginForm 响应也包含以前的值

即使服务器返回适当的响应标头,Firefox 也不允许 CORS 请求

Ajax

ajax

Ajax

Django( Ajax )