具有显式域的localhost上的Cookie


191

我一定缺少关于Cookie的一些基本知识。在本地主机上,当我设置在服务器端的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都可以使用,但是当我在“首选项”中检查cookie列表时,即使该域在localhost(在列表分组中)下列出,该域也设置为localhost.local。

Safari 4: localhost和.localhost都可以使用,但是在“首选项”中它们始终列为.localhost。另一方面,没有显式域的cookie,仅显示为localhost(无点)。

本地主机有什么问题?由于存在许多这样的不一致,因此必须有一些涉及本地主机的特殊规则。另外,我还不完全清楚为什么必须在域名前加点号?RFC 2109明确指出:

域属性的值不包含嵌入的点或不以点开头。

为什么?该文件表明它必须在安全方面做些事情。我不得不承认我还没有阅读整个规范(以后可能会做),但这听起来有些奇怪。基于此,将不可能在本地主机上设置cookie。


13
6岁的线程,这仍然是一个问题。我正在使用Chrome v40。看这里
盖伊2015年

5
Chrome 43 ...仍然是一个错误。
埃文·卡罗尔

4
Chrome浏览器54在这里,没有解决
瓦希德·阿米里

6
Chrome 73 ..仍然面临相同的问题。:(
Code_Crash

2
任何人都可以解决这个问题?仍然面临着同样的问题*** .. 看到这样的答案
Bonjour123

Answers:


235

根据设计,域名必须至少包含两个点;否则,浏览器将认为它们无效。(请参见http://curl.haxx.se/rfc/cookie_spec.html上的参考)

使用时localhost,必须完全省略cookie域。仅将其设置为""or NULLFALSE代替"localhost"是不够的。

对于PHP,请参见http://php.net/manual/en/function.setcookie.php#73107上的注释。

如果使用Java Servlet API,则完全不要调用该cookie.setDomain("...")方法。


93
不知道为什么每个人都为此+1,我将cookie的域设置为null或false或空字符串,并且如果在localhost上仍然无法保存。
贾斯汀

5
我在RFC6265中看不到域中的两个点: tools.ietf.org/html/rfc6265#section-5.2.3 .Net表示将本地域中的所有主机都设置为“ .local”。这似乎与Opera / Safari msdn.microsoft.com/en-us/library/ckch3yd2.aspx
MandoMando 2011年

9
@Justin:嗯,Domain=设置cookie时可能需要完全省略该参数。如果仅将域设置为null或空,也许您的框架将发送Domain=具有该值的参数,而不是忽略它?检查,例如萤火虫。
sleske 2012年

2
@Ralph,一百万,谢谢,这件事使我疯狂了几个小时。希望将Domain设置为null(我在.Net服务器堆栈中),就像一个超级魅力。
Xose Lluis 2013年

4
这句话措辞不佳。“设置为null或false或空字符串”应显示为“完全不设置Cookie的“域”部分。” 例如,使用简单的测试完全忽略cookie的domain部分对localhost起作用:((domain && domain !== "localhost") ? ";domain="+domain : "")
L0j1k 2015年

33

我大致上同意@Ralph Buchfelder,但这是通过尝试在本地计算机上复制具有多个子域(例如example.com,fr.example.com,de.example.com)的系统时进行的实验来放大的( OS X / Apache / Chrome | Firefox)。

我已经编辑了/ 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上工作,并且没有设置domain参数,则cookie对于fr.localexample.com正确存储,但在其他子域中不可见。

如果我使用“.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>

30

本地主机:您可以使用:domain: ".app.localhost",它将起作用。在“域”参数需要1个或多个点的域名设置Cookie。然后,您可以使会话跨localhost子域工作,例如:api.app.localhost:3000


1
还测试了并使用Express 3.x在node.js服务器上工作,在express.session({cookie: { domain: '.app.localhost', maxAge: 24 * 60 * 60 * 1000 }})
AmpT 2014年

3
如果您正在使用本地域,则应选择“ THIS”作为答案!在子域之前放置一个点可解决我的问题。
Foxhoundn

1
那么,这个.app.来自何处的前置呢?它是某些SPEC的一部分吗?它是否适用于所有不合格的域(没有两个点的域)?此外,这是否可以与旧版浏览器一起使用?:^)
user2173353 '16

哦,我现在明白了,这只是愚弄浏览器。好。
user2173353 '16

14

当cookie设置为具有显式域“ localhost”时,如下所示...

Set-Cookie:名称=值; domain = localhost ; expires =星期四,2009年7月16日21:25:05 GMT;路径= /

...然后浏览器将其忽略,因为它不包含至少两个句点,并且不是七个经过特殊处理的顶级域之一

...域中必须至少包含两(2)或三(3)个句点,以防止出现以下形式的域:“。com”,“。edu”和“ va.us”。在以下列出的七个特殊顶级域之一中失败的任何域都只需要两个句点。其他任何域都至少需要三个。七个特殊的顶级域是:“ COM”,“ EDU”,“ NET”,“ ORG”,“ GOV”,“ MIL”和“ INT”。

请注意,上述期间数可能假设需要提前期。但是,这个时期在现代浏览器被忽略了,应该读为...

至少一(1)或两(2)个周期

请注意,domain属性的默认值是生成cookie响应的服务器的主机名

因此,对于未为本地主机设置cookie的一种解决方法是,简单地不指定域属性,而让浏览器使用默认值-这似乎没有与域属性中的显式值相同的约束。


我没有DV,但是我猜想别人这样做的原因是因为您的回答并没有真正增加太多价值。在其他答案中都讨论了两个时间段要求和将域属性留为空白。另外,您添加的有关顶级域的内容似乎不正确。根据我的经验,这不是必需的。
TTT

@TTT不知道您是否已回答我所说的问题,因为TLD会忽略前置时间,因此我说该时间应至少为1或2个时间段?因此,我提供了一些有关该问题的背景知识,并补充了一点,我认为其他地方都没有涉及这一点-明确域的规则与浏览器默认使用的规则不同。似乎为我增加了一些价值。
Scott Munro

1
将域保留为空(根本不设置)不会导致Chrome保留本地主机的cookie。它仍然忽略它。请注意,这仅适用于“永久” Cookie(设置过期日期的cookie),因为它将挂接到localhost的“会话” cookie(未设置过期日期的cookie)。
Triynko

3

结果因浏览器而异。

Chrome-127.0.0.1工作正常,但localhost .localhost和“”无效。Firefox- .localhost有效,但localhost,127.0.0.1和“”无效。

尚未在Opera,IE或Safari中进行测试


3
刚刚使用Chrome V.22.0.1229.94 m对其进行了测试:在不提供Domain=参数的情况下为localhost设置cookie是可行的。Domain=也可以,但Domain=localhost不能。
sleske 2012年

3

我自己花了很多时间对这个问题进行故障排除。

使用PHP,此页面上的任何内容都不适合我。最终,我在代码中意识到PHP的session_set_cookie_params()的“安全”参数始终被设置为TRUE。

由于我没有使用https访问localhost,因此我的浏览器永远不会接受Cookie。因此,我修改了代码的这一部分,以根据$ _SERVER ['HTTP_HOST']是否为“ localhost”有条件地设置“安全”参数。现在运作良好。

我希望这可以帮助别人。


2

如果你从另一个域设置cookie(即你通过做一个XHR跨源请求设置cookie),那么你需要确保你的设置withCredentials属性为true的XMLHttpRequest的使用来获取cookie的描述在这里


是的,即使那样。它仍然不适用于跨域请求。浏览器-Safari,IE 11
Rohit Kumar,

2

您可以利用它,localhost.org或者说.localhost.org它将始终解决127.0.0.1


1

我使用127.0.0.1作为域在本地进行了更好的运气测试。我不确定为什么,但是我将结果与localhost和.localhost等混合使用。


1

所建议的修复均不适合我-将其设置为null,false,添加两个点等-不起作用。

最后,如果它是localhost,那么我刚刚从cookie中删除了该域,现在该域在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=/;';
    }

1

我遇到了同样的问题,并通过在cookie名称本身中放置2个点而不指定任何域来解决此问题。

set-cookie: name.s1.s2=value; path=/; expires=Sun, 12 Aug 2018 14:28:43 GMT; HttpOnly

1

当您使用https://<local-domain>then之后似乎出现了问题http://<local-domain>。网站设置http://请求后,该站点不会发送带有请求的Cookie https://。强制重新加载并清除缓存无济于事。只有手动清除Cookie才有效。另外,如果我在https://页面上清除它们,则http://页面将再次开始工作。

看起来与“严格的安全cookie”有关。这里的解释很好。它于2017-04-19 在Chrome 58发布

Chrome似乎确实记录了安全cookie和非安全cookie,因为单击地址栏图标时,它将根据页面的协议显示正确的cookie。

但是Developer tools > Application > Cookies,如果在同一域中存在具有相同名称的安全cookie,则不会显示非安全cookie,也不会随任何请求一起发送该非安全cookie。这似乎是一个Chrome错误,或者如果预期会发生这种情况,则应该使用某种方法在http页面上查看安全cookie 并指出它们已被覆盖。

解决方法是使用不同的已命名Cookie,具体取决于它们是用于http站点还是https站点,并为您的应用程序专门命名。一个__Secure-前缀表示该cookie应严格安全的,也是一个很好的做法,因为安全和非安全的不会发生碰撞。前缀还有其他好处

/etc/hosts对https和http访问使用不同的域也可以,但是一次意外https://localhost访问将阻止任何同名的cookie在http://localhost网站上工作-因此,这不是一个好的解决方法。

我已提交了Chrome错误报告


0

document.cookie = valuename +“ =” + value +“;” +到期+“; domain =; path = /”;

这个“域=;路径= /”; 将采用动态域,因为其Cookie可以在子域中使用。如果您想在localhost中测试,它将正常工作


0

这里没有答案对我有用。我通过将PHP作为页面的第一件事来解决了它。

与其他标头一样,必须在脚本的任何输出之前发送cookie(这是协议限制)。这要求您在任何输出(包括和标记以及任何空格)之前都先调用此函数。

来自http://php.net/manual/en/function.setcookie.php


但这与问题无关,只是没有犯在标头之前发送任何其他输出的错误
Marnes


0

我玩了一下。

Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=localhost; Path=/

从现在开始可以在Firefox和Chrome中使用。但是,我没有找到使它与curl配合使用的方法。我尝试了Host-Header和--resolve,没有运气,感谢任何帮助。

但是,如果我将其设置为curl,它将可以卷曲

Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=127.0.0.1; Path=/

代替。(这不适用于Firefox。)


0

另一个重要的详细信息expires =应该使用以下日期时间格式:Wdy,DD-Mon-YYYY HH:MM:SS GMTRFC6265-第4.1.1节)。

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

5
-1 Cookie的当前规范是RFC 6265,tools.ietf.org/html/rfc6265,其中明确指出允许使用4位数字的年份。因此,使用2位数的年份是个坏主意,不同的浏览器会使用不同的年份。
sleske 2011年

正确。引用RFC6265第4.1.1节
Zen Cart

4
正确,但是回到2011年6月,我没有找到该RFC。因此,尽管此信息现在不正确,但当我编写该信息时却不正确。
特拉马扎

4
不要轻描淡写,事情会改变,我们都需要帮助确保答案保持最新。只需使用@sleske给您的最新信息更新您的答案,并感谢他的帮助。
马修·珀登

0

经过大量实验并阅读了各种帖子,此方法有效。我可以设置多个cookie,将它们读回,并将时间设置为负数并删除它们。

func addCookie(w http.ResponseWriter, name string, value string) {
    expire := time.Now().AddDate(0, 0, 1)
    cookie := http.Cookie{
       Name:    name,
       Value:   value,
       Expires: expire,
       Domain:  ".localhost",
       Path:    "/",
    }
    http.SetCookie(w, &cookie)
}

0

对我来说唯一有效的方法是设置Path=/cookie。

此外,路径属性的默认值似乎因浏览器而异,尽管我仅测试了其中两个(Firefox和Chrome)。

Chrome尝试按原样设置Cookie;如果标头中path省略了属性Set-Cookie,则将不会存储和忽略该属性。

但是,即使没有显式path属性,Firefox也会存储cookie 。它只是用请求的路径设置它;我的请求网址是/api/v1/users,并且路径设置为/api/v1自动。

无论如何,两个浏览器都可以在path设置为/甚至没有显式域(例如)的情况下工作Domain=localhost。因此,每个浏览器处理Cookie的方式有所不同。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.