本地主机上具有明确域的Cookie

问题描述 投票:168回答:18

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

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

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

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

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

cookies setcookie
18个回答
217
投票

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

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

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

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


1
投票

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

看起来与“严格的安全cookie”有关。很好的解释here。是2017年4月19日的released in Chrome 58

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

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

解决方法是使用不同名称的cookie,具体取决于它们是用于http站点还是https站点,并为其命名特定于您的应用程序。 __Secure-前缀表示cookie应该严格安全,这也是一个好习惯,因为安全和非安全不会冲突。前缀也有other benefits

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

我已提交Chrome bug report


1
投票

您可以使用localhost.org或更确切地说是.localhost.org,它将始终解析为127.0.0.1


0
投票

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


0
投票

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


0
投票

有一个issue on Chromium open since 2011,如果您将域显式设置为'localhost',则应将其设置为falseundefined


0
投票

我玩了一下。


0
投票

另一个重要的细节,expires =


0
投票

[如果要从另一个域设置cookie(即,通过发出XHR跨源请求来设置cookie),则需要确保在用于获取XMLHttpRequest的XMLHttpRequest上将withCredentials属性设置为true Cookie here


0
投票

[经过大量的实验并阅读了各种文章,此方法有效。我可以设置多个cookie,将它们重新读回,并将时间设置为负,然后将其删除。


29
投票

我大致上同意@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,并且is在其他子域中可见。

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

28
投票

localhost:您可以使用:domain: ".app.localhost",它将起作用。域名中的'domain'参数需要1个或多个点用于设置cookie。然后,您可以使会话跨localhost子域工作,例如:api.app.localhost:3000


13
投票

[如下设置cookie的显式域为'localhost'时...

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

...然后浏览器将其忽略,因为它是does not include at least two periods and is not one of seven specially handled, top level domains

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

请注意,以上期间的数量可能假定需要前置时间。但是,此时间段为ignored in modern browsers,可能应读取为...

至少一(1)或两(2)期间

请注意,域属性的默认值为the host name of the server which generated the cookie response

因此未为localhost设置cookie的解决方法是仅不指定域属性并让浏览器使用默认值-这似乎与域属性中的显式值没有相同的约束做。


3
投票

我的结果因浏览器而异。

Chrome-127.0.0.1有效,但是localhost .localhost和“”无效。Firefox- .localhost有效,但localhost,127.0.0.1和“”无效。

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


3
投票

自己花费了大量时间来解决此问题。

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

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

我希望这对某人有帮助。


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
© www.soinside.com 2019 - 2024. All rights reserved.