浏览器中存在Cookie,但php $_COOKIE为空

9

我的项目在本地服务器上可以正常运行,但在生产服务器上无法正常工作,因为服务器无法看到cookie。我已经制作了一个最小化的代码版本,在该服务器上重现了该问题:

<?php

if(!isset($_COOKIE['foo'])){
    setcookie('foo', 'bar', time() + 7*24*60*60, '/');
    echo "Cookie was not found, so we just created it.";
} else {
    echo "Cookie was found!";
}

?>
无论我刷新这个页面多少次,都会收到“未找到”消息。每当我尝试记录 $_COOKIE 变量时,都会得到一个空数组。但是:
  • Cookie存在于浏览器中,并与请求正确发送
  • Cookie在同一文件中设置和读取(不是 path 的问题)
  • setcookie 之前没有输出,文件以UTF8编码而无BOM
我认为这是服务器配置问题,因为该代码在本地运行正常,但我不知道该去哪里查找。有人遇到过这种情况吗?你知道是什么原因?
如果您需要更多信息,请告诉我,我会将其添加到我的问题中。谢谢!

是否涉及任何CDN和/或缓存服务器会吞噬cookie? - deceze
5
请检查您的服务器的php.ini文件中是否有variables_order指令。其中是否缺少了字母C?http://php.net/manual/en/ini.core.php#ini.variables-order - Michael Berkowski
@deceze,已经设置了Varnish缓存,但是这个页面没有被缓存。你认为这可能会吞噬cookie吗?@Michael,感谢您的建议,我已经检查过了,看起来没问题:variables_order = EGPCS - blex
2
缓存服务器通常默认情况下不会传递cookie,除非你明确地将它们列入白名单。 - deceze
1
@deceze 我已经和一位同事谈过关于Varnish的事情,他说了和你一样的话:它基于白名单过滤cookie。感谢你的帮助,请把它作为答案发布,这样我就可以接受它 :) - blex
我有同样的问题。如果我使用 POST 方法(从一个简单的 data:text/html, <form method="post"... 页面),用 var_dump($_COOKIE) 显示为 []。直接发送 GET 请求的方式打开相同的页面会正确显示 cookie。使用 method="put"method="delete"method="get" 等方法均可以正常工作。 - user10398534
4个回答

6
如果涉及到缓存服务器或CDN,则可能会根据白名单过滤cookie。这是为了改善缓存,因为每个具有唯一cookie集的请求都需要视为与其他请求不同,并且无法缓存(您可能会根据cookie从服务器收到不同的回复,因此缓存服务器无法向您提供以前客户端的缓存响应)。由于许多服务设置的cookie可能会发送到服务器(例如分析包),但绝对不会影响响应内容,因此默认情况下遵循所有cookie通常会完全破坏缓存。
配置负责的缓存服务器以特别关注您的cookie并将其转发到源服务器。如果您有很多不同的cookie,请考虑给它们一个公共前缀并将其列入白名单(例如foo-*)。

好的解释。另外,感谢您关于前缀的提示,这可能对我很有帮助,避免每次需要新的cookie时都要问我的同事。 - blex

6

我刚刚处理了与此相同的问题,我的生产服务器允许我使用setcookie('cookieNameHere', $cookieValueHere, time() + (86400 * 365), "/")创建浏览器cookie,但是$_COOKIE变量始终为空数组。

问题在于出于安全原因,我的生产服务器阻止PHP直接访问$_COOKIE变量内容。

我的解决方案是使用以下函数通过JavaScript访问cookie值:

    function getCookie(cname) {
      var name = cname + "=";
      var decodedCookie = decodeURIComponent(document.cookie);
      var ca = decodedCookie.split(';');
      for(var i = 0; i <ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
          c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
          return c.substring(name.length, c.length);
        }
      }
      return "";
    }

我继续通过PHP创建/更新cookie。

顺便提一下,我正在处理托管在WP-Engine上的WordPress站点。有关详细说明以及其他选项,请参见此页面,以了解如果您绝对需要通过PHP访问cookie值(ADMIN-AJAX调用等)时的情况。


1

我曾遇到类似问题,最后发现是HAProxy配置问题。在服务器和用户之间是否有任何负载均衡器?


谢谢您的输入,这可能是情况,我会向我的同事询问。 - blex

-1

我认为你的问题是服务器时间。使用time()函数检查你的时间并与本地时间进行比较。也许其中一个是错误的。


谢谢您的回答,但我已经检查了时间,它与我的机器相同。 - blex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接