我一定是忽略了饼干的一些基本特性。在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是不可能的。


当前回答

我基本上同意@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>

其他回答

所有建议的修复程序都不适合我——设置为null、false、添加两个点等等——都不起作用。

最后,我只是从cookie中删除了域,如果它是localhost,现在在Chrome 38中为我工作。

以前的代码(不工作):

document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';domain=.' + document.domain + ';path=/;';

新代码(现在工作):

 if(document.domain === 'localhost') {
        document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';path=/;' ;
    } else {
        document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';domain=.' + document.domain + ';path=/;';
    }

另一个重要的细节是,expires=应该使用以下日期时间格式:Wdy, DD-Mon-YYYY HH:MM:SS GMT (RFC6265 -章节4.1.1)。

Set-Cookie:
  name=value;
  domain=localhost;
  expires=Thu, 16-07-2019 21:25:05 GMT;
  path=/

不同浏览器的结果也不同。

Chrome- 127.0.0.1工作,但localhost .localhost和“”不能。 Firefox- .localhost可以工作,但localhost、127.0.0.1和“”不能工作。

没有在Opera, IE或Safari中测试过

我有一个类似的问题,我的后端和前端运行在本地主机,但不同的端口。为了解决这个问题,我在Set-Cookie中省略了域,并在我的请求选项中使用了凭据:true。

在这里看到的

尝试了上面所有的选项。对我有用的是:

确保对服务器的请求将withCredentials设置为true。来自不同域的XMLHttpRequest不能为自己的域设置cookie值,除非在发出请求之前将withCredentials设置为true。 不要设置域名 设置路径= /

结果Set-Cookie报头:

Set-Cookie: session_token=74528588-7c48-4546-a3ae-4326e22449e5; Expires=Sun, 16 Aug 2020 04:40:42 GMT; Path=/