27

编辑 - 使用 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)
  3. 下一个 XHR 请求不会将该 cookie 发送回服务器,因此 express 无法识别用户,因此会创建一个新的会话 cookie,依此类推。
4

4 回答 4

36

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

xhr.withCredentials = true;

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

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

于 2012-07-22T15:01:00.060 回答
6

我以前也遇到过这种情况,我可以说这很愚蠢。

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

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

因此,当服务器设置 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
于 2012-07-22T15:00:51.493 回答
5

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

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

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

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

于 2017-05-10T17:34:15.680 回答
2

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

于 2013-05-19T13:07:40.370 回答