我有以下要求:
问题是,客户端可能落后于服务器多少分钟。在服务器端,我将cookie设置为
setcookie($cooName,$cooVal,time()+500,"/");
但是现在如果客户端计算机比服务器落后500秒,则上面的代码将生成一个cookie,该cookie将在1000秒内到期,而不是500秒。
我正在考虑将客户的时间戳发送到服务器并在那时设置cookie。像这样的东西:
setcookie($cooName,$cooVal,$_GET['clientTS']+500,"/");
但是如果客户端落后500秒,如果我设置了这样一个已经过时的cookie,它就不会被设置。如果cookie过期,如何在客户端和服务器之间实现时间同步?
答案 0 :(得分:10)
不幸的是, Expires 是一个绝对日期,取决于用户代理的本地日期。正确结束后,这可能导致cookie过期不准确。
这也是IETF第一次Netscape’s original proposal标准化的原因,用绝对过期日期替换了相对过期日期, Max-Age 属性指定了以秒为单位的时间饼干发布的时间点。已过时的RFC 2109 RFC 2965也做了同样的事情。与RFC 6265一样,这是目前最新的Cookie规范。
根据RFC 6265的Cookie也允许使用 Max-Age 的相对日期和使用 Expires 的绝对日期来指定到期日期,后者主要用于向后兼容性:
如果cookie同时具有Max-Age和Expires属性,则Max-Age属性具有优先权并控制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);
}