我有以下要求:
- 为服务器域创建一个cookie
- 该 cookie 将在 x 秒后过期,比如 200 或 500 秒。
问题是,客户端可能会比服务器滞后几分钟。在服务器端,我将 cookie 设置为
setcookie($cooName,$cooVal,time()+500,"/");
但是现在如果客户端计算机落后于服务器 500 秒,上面的代码将影响一个 cookie,该 cookie 将在 1000 秒而不是 500 秒后过期。
我正在考虑将客户端的时间戳发送到服务器并在那个时间设置 cookie。像这样:
setcookie($cooName,$cooVal,$_GET['clientTS']+500,"/");
但是如果客户端落后 500 秒,并且如果我设置了这样一个回溯的 cookie,它就不会被设置。如何在 cookie 过期的情况下实现客户端和服务器之间的时间同步?
最佳答案
不幸的是,Expires 是一个绝对日期并且取决于用户代理的本地日期。正如您得出的正确结论,这可能会导致 cookie 过期不准确。
这也是为什么IETF首先对Netscape’s original proposal进行标准化的原因, 将绝对到期日期替换为相对到期日期,Max-Age 属性指定从发布 cookie 的时间点开始的时间(以增量秒为单位)。 RFC 2965 ,那个过时的 RFC 2109,做了同样的事情。正如RFC 6265 ,这是目前最新的 cookie 规范。
根据 RFC 6265 的 Cookie 也允许通过使用 Max-Age 的相对日期和使用 Expires 的绝对日期来指定到期日期,后者主要用于向后兼容性:
If a cookie has both the Max-Age and the Expires attribute, the Max-Age attribute has precedence and controls the expiration date of the cookie.
因此您可以编写自己的函数来模仿这种行为:
$maxage = 12345;
$expires = date(DATE_COOKIE, time()+$maxage);
header("Set-Cookie: $name=$value, Expires=$expires, Max-Age=$maxage, …");
这是一个示例函数:
function set_cookie($name, $value=null, $maxage=null, $path=null, $domain=null, $secure=false, $httponly=false) {
$cookie = rawurlencode($name) . '=' . rawurlencode($value);
$attributes = array();
if (!is_null($maxage)) {
$maxage = intval($maxage);
$attributes[] = 'Expires='.date(DATE_COOKIE, $maxage > 0 ? time()+$maxage : 0);
$attributes[] = 'Max-Age='.$maxage;
}
if (!is_null($path)) {
$attributes[] = 'Path='.rawurlencode($path);
}
if (!is_null($domain)) {
$attributes[] = 'Domain='.rawurlencode($domain);
}
if ($secure) {
$attributes[] = 'Secure';
}
if ($httponly) {
$attributes[] = 'HttpOnly';
}
header('Set-Cookie: '.implode('; ', array_merge(array($cookie), $attributes)), false);
}
关于php - 我们可以根据客户的时间在php中设置一个cookie吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9063029/