【问题标题】:Browsers not sending back cookies when using CORS XHR使用 CORS XHR 时浏览器不发回 cookie
【发布时间】:2012-07-21 00:24:28
【问题描述】:

编辑 - 使用 Chrome 网络检查器查看 cookie,似乎无论 cookie 的过期值是什么,浏览器都将其设置为会话 cookie 并根据请求将其删除。

我正在使用 Node.js 和 Express 为我正在教授的课程构建一个 CORS 示例。

但是,虽然 cookie 是从服务器设置的,但它们不会在后续请求中被发送回服务器。这几乎意味着我不能使用任何琐碎的会话管理器。

知道我在这里缺少什么吗?为什么浏览器不将域设置的 cookie 发送回该域?这不应该自动发生吗?

编辑 - 一些代码示例: 设置 XHR 请求:

var xhr = new XMLHttpRequest();

xhr.open(method, url, true);
xhr.widthCredentials = true;

xhr.onreadystatechange = function(res){
    if (xhr.readyState == 4){
        cb(res,xhr);
    }
};

xhr.setRequestHeader("Content-Type",'application/json');

xhr.setRequestHeader('Accept','application/json');

xhr.send(JSON.encode({param:some_param})); 

服务器:

function allowCrossDomain(req,res,next) {  
    res.header('Access-Control-Allow-Credentials', true);
    res.header('Access-Control-Allow-Origin', req.headers.origin);
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type,Accept,X-Requested-With');

    if (req.method!='OPTIONS') return next();

    res.send(204);
}                 

//while configuring express
app.use(allowCrossDomain)

还值得一提的是,我尝试了各种npm 中间件,它们做同样的事情,没有明显的区别

关于场景:

  1. 使用 XHR 发出 CORS 请求
  2. 服务器设置了一个 cookie,该 cookie 正在成功发送回客户端(快速会话 cookie)
  3. 下一个 XHR 请求不会将该 cookie 发送回服务器,因此 express 无法识别用户,因此会创建一个新的会话 cookie,依此类推。

【问题讨论】:

  • 代码值一千字。 :-) 显示设置所有 CORS 标头、设置 cookie 等的代码。
  • 您的服务器是否使用虚拟机?
  • 只是为了澄清一下:您说的是域中的服务器设置的 cookie 跨域调用正在被进行,对吗?
  • 还有check out this stuff,特别是关于“省略凭据”标志的部分,以及用户代理如何强制它始终为true
  • 看起来你的代码中有错字。应该是 xhr.withCredentials = true;不是 xhr.widthCredentials = true;

标签: javascript node.js express cors


【解决方案1】:

我刚遇到这个问题,我的解决方案是添加cookie的路径,所以添加cookie时必须使用:

document.cookie = 'cookieName=cookieValue;path=/';

这样浏览器将能够在新请求中发送 cookie。

PS:如果您使用跨域请求,您还需要xhr.withCredentials = true;

【讨论】:

  • 对此赞不绝口,这让我陷入了一个循环,试图做完全相同的事情,通过 javascript 设置 cookie,设置 withCredentials = true,但直到我在 cookie 上有路径设置我的浏览器(chrome)不会传输该 cookie
【解决方案2】:

除了我读过的内容外,我对此一无所知,但根据the MDN docs,XHR 对象上有一个“withCredentials”属性,需要设置:

xhr.withCredentials = true;

默认为false。如果没有设置该标志,则不会传输 cookie,并且响应中的 cookie 标头将被忽略。

edit — 我发誓我读过你的问题几次,但我完全错过了你提到的 flag 。对不起。但是,由于这不是完全浪费,我还要提到您的服务器需要在响应标头中将“Access-Control-Allow-Credentials”标志设置为true,并且“Access-Control- Allow-Origin" 设置为您当前的协议 + 主机 + 端口。

【讨论】:

  • 如果你读过这个问题:including enabling the withCredentials flag
  • @FlorianMargaine 哎呀 :-) 好吧,无论如何我都会扩展答案
  • @XiroX 正如@Mahes 在问题 withCredentials 的 cmets 中发现的,实际上在您的代码中拼写错误,这可能是您没有收到 cookie 发送的原因。
【解决方案3】:

我遇到了类似的问题,结果是浏览器设置阻止了第三方 cookie(Chrome > 设置 > 高级设置 > 隐私 > 内容设置 > 阻止第三方 cookie 和站点数据)。解锁解决了问题!

【讨论】:

  • 这并没有真正的帮助,因为您无法控制用户的设置。当然,在这种情况下,因为他正在教一门课,所以他可以告诉他的学生禁用该设置,但在现实世界的场景中,这将无济于事。
【解决方案4】:

这个happened to me之前,我可以说它很愚蠢。

如果您使用的是虚拟机,您通常会在需要时暂停/恢复它等。

这意味着虚拟机的日期通常比主机或您正在使用的任何客户端晚几天(或更多)。

因此,当服务器设置 cookie 的过期日期(通常在当前日期后几个小时)时,它在客户端上已经过期。因此,客户端不会保留它。

要在虚拟机上更新日期,我建议你直接使用ntpdate,或者你可以手动设置日期看看是否有问题:

# what's the date?
date
# You'll see if it's the problem already

# If it is, here is how to manually set it
date -set 2012-07-22 # yyyy-mm-dd
date -set 17:00:42 # hh:mm:ss

【讨论】:

  • @XiroX 你检查服务器上的日期了吗?
  • 是的 - 这不是日期问题 - 服务器发送的日期很好
  • 哈哈类似的事情曾经发生在我身上。我很高兴我手边没有棒球棒。
猜你喜欢
  • 2013-05-01
  • 2021-10-25
  • 2011-08-07
  • 1970-01-01
  • 2019-11-04
  • 2020-02-29
  • 2016-08-23
  • 1970-01-01
  • 2019-03-28
相关资源
最近更新 更多