我一定是忽略了饼干的一些基本特性。在localhost上,当我在服务器端设置cookie并显式地将域指定为localhost(或.localhost)时。有些浏览器似乎不接受cookie。
Firefox 3.5:我在Firebug中检查了HTTP请求。我看到的是:
Set-Cookie:
name=value;
domain=localhost;
expires=Thu, 16-Jul-2009 21:25:05 GMT;
path=/
或者(当我设置域为.localhost时):
Set-Cookie:
name=value;
domain=.localhost;
expires=Thu, 16-Jul-2009 21:25:05 GMT;
path=/
在这两种情况下,cookie都不会被存储。
IE8:我没有使用任何额外的工具,但cookie似乎没有被存储,因为它没有在后续的请求中被发送回来。
Opera 9.64: localhost和.localhost都可以工作,但是当我检查Preferences中的cookie列表时,域被设置为localhost。Local,即使它列在localhost下(在列表分组中)。
Safari 4: localhost和.localhost都可以工作,但它们总是在首选项中列出为.localhost。另一方面,一个没有显式域的cookie,它只显示为localhost(没有点)。
localhost有什么问题?由于存在如此多的不一致,必须有一些涉及localhost的特殊规则。另外,我也不完全清楚为什么域名必须以一个点作为前缀?RFC 2109明确指出:
Domain属性的值
不包含或不包含嵌入点
从一个点开始。
为什么?该文档表明它必须在安全性方面做一些事情。我必须承认我没有阅读完整的规范(可能以后会读),但它听起来有点奇怪。基于此,在本地主机上设置cookie是不可能的。
当您使用https://<local-domain>然后使用http://<local-domain>时,似乎有一个问题。https:// site设置cookie后,http:// site不会随请求一起发送cookie。强制重载和清除缓存没有帮助。只有手动清除cookie才能工作。同样,如果我在https://页面上清除它们,那么http://页面将重新开始工作。
看起来和"严格安全cookie "有关。解释得很好。它于2017-04-19在Chrome 58中发布。
看起来Chrome确实记录了安全cookie和非安全cookie,因为当点击地址栏图标时,它会根据页面的协议显示正确的cookie。
但是开发工具>应用程序> Cookies将不会显示一个非安全cookie,当有一个安全cookie的相同名称的同一域,它也不会发送非安全cookie与任何请求。这似乎是一个Chrome错误,或者如果这种行为是预期的,应该有一些方法来查看安全cookie时,http页面和一个指示,他们正在被覆盖。
解决方法是使用不同的命名cookie,这取决于它们是用于http站点还是https站点,并根据您的应用程序具体命名它们。__Secure-前缀表明cookie应该是严格安全的,这也是一个很好的实践,因为安全和非安全不会冲突。前缀还有其他好处。
使用不同的/etc/hosts域进行https和http访问也可以,但是一次意外的https://localhost访问将阻止任何相同名称的cookie在http://localhost站点上工作-所以这不是一个好的解决方案。
我已经提交了Chrome错误报告。
我基本上同意@Ralph Buchfelder的观点,但这里有一些放大,通过在我的本地机器(OS X / Apache / Chrome|Firefox)上尝试复制具有几个子域(例如example.com, fr.example.com, de.example.com)的系统的实验。
我编辑了/etc/hosts,将一些虚构的子域指向127.0.0.1:
127.0.0.1 localexample.com
127.0.0.1 fr.localexample.com
127.0.0.1 de.localexample.com
如果我在fr.localexample.com上工作,并且去掉域参数,则为fr.localexample.com正确存储cookie,但在其他子域中不可见。
如果我使用“。localexample.com”的域名,cookie将正确存储为fr.localexample.com,并且在其他子域中可见。
如果我使用的域是“localexample.com”,或者当我尝试的域只是“localexample”或“localhost”时,cookie没有被存储。
如果我使用“fr.localexample.com”或“。fr.localexample.com”的域,cookie将正确地存储为fr.localexample.com,并且(正确地)在其他子域中不可见。
所以定义域中至少需要两个点的要求似乎是正确的,尽管我不明白为什么它应该是正确的。
如果有人想尝试一下,这里有一些有用的代码:
<html>
<head>
<title>
Testing cookies
</title>
</head>
<body>
<?php
header('HTTP/1.0 200');
$domain = 'fr.localexample.com'; // Change this to the domain you want to test.
if (!empty($_GET['v'])) {
$val = $_GET['v'];
print "Setting cookie to $val<br/>";
setcookie("mycookie", $val, time() + 48 * 3600, '/', $domain);
}
print "<pre>";
print "Cookie:<br/>";
var_dump($_COOKIE);
print "Server:<br/>";
var_dump($_SERVER);
print "</pre>";
?>
</body>
</html>