通过HTTPS的HTTP Cookie和Ajax请求

HTTP Cookies and Ajax requests over HTTPS

我知道之前已经以各种形式提出过这个问题,但我似乎无法解决这个问题。
我已经尝试使用jQuery和本机JS API来发出Ajax请求。

我的情况如下(见附图):

  • 浏览器发出HTTP请求
  • 服务器响应并设置持久性Cookie
  • 浏览器发出HTTP Ajax请求,Cookie就没问题了
  • 服务器按预期响应,更新Cookie
  • 浏览器发出HTTPS Ajax请求,Cookie不再存在(?!)
  • 服务器提供"默认"响应,因为没有Cookie(意外行为)
  • 在任何人开始关于跨域请求的讲座之前,请先说明一些事情:

    • 我知道这是一个跨域请求(不同的协议),这就是服务器在响应中设置Access-Control-Allow-Origin标头的原因(我使用的是Chrome和Firefox,两者都支持CORS)
    • 但我也知道,HTTP cookie应该可以通过HTTPS进行管理(参见此处),因为主机是相同的
    • (编辑)为一般域(例如.domain.ext)正确设置cookie,并且HttpOnly和Secure标志都没有设置

    那么,为什么,为什么,为什么浏览器在进行HTTPS Ajax调用时不会传递cookie?有任何想法吗?我快要忘了......

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
         +-----------+ HTTP Request     +-----------+
         |Browser    |+---------------->|Server     |
         +-----------+                  +-----------+

                       HTTP Response
                      <----------------+
                       Set-cookie

                       Ajax HTTP Req.
                      +---------------->
                       Cookie (OK)

                       HTTP Response
                      <----------------+
                       Set-cookie (OK)

                       Ajax HTTPS Req.
                      +---------------->
                       No Cookie (!!!)


    好的,找到了cookie问题的解决方案。

    请参阅XHR规范,jQuery文档和StackOverflow。

    切换协议和/或子域时发送cookie的解决方案是将withCredentials属性设置为true

    例如。 (使用jQuery)

    1
    2
    3
    4
    5
    6
     $.ajax( {
       /* Setup the call */
       xhrFields: {
         withCredentials: true
       }
     });


    Document.cookie和Ajax Request不共享cookie。 否则,ajax无法从document.cookie或响应标头访问cookie。 它们只能由远程域控制。

    如果您首先通过ajax从服务器获得包含cookie的响应,那么您可以通过cookie向服务器请求ajax通信。

    对于这种情况,你写下面的代码(jQuery)

    1
    2
    3
    4
    5
     $.jajx({
            xhrFields : {
              withCredentials : true
            }
       });

    请参阅此文章和演示