Cookies on localhost with explicit domain
I must be missing some basic thing about cookies. On localhost, when I set a cookie on server side and specify the domain explicitly as localhost (or .localhost). the cookie does not seem to be accepted by some browsers.
Firefox 3.5: I checked the HTTP request in Firebug. What I see is:
Set-Cookie:
name=value;
domain=localhost;
expires=Thu, 16-Jul-2009 21:25:05 GMT;
path=/
or (when I set the domain to .localhost):
Set-Cookie:
name=value;
domain=.localhost;
expires=Thu, 16-Jul-2009 21:25:05 GMT;
path=/
In either case, the cookie is not stored.
IE8: I did not use any extra tool, but the cookie does not seem to be stored as well, because it's not being sent back in subsequent requests.
Opera 9.64: Both localhost and .localhost work, but when I check the list of cookies in Preferences, the domain is set to localhost.local even though it's listed under localhost (in the list grouping).
Safari 4: Both localhost and .localhost work, but they are always listed as .localhost in Preferences. On the other hand, a cookie without an explicit domain, it being shown as just localhost (no dot).
What is the problem with localhost? Because of such a number of inconsistencies, there must be some special rules involving localhost. Also, it's not completely clear to me why domains must be prefixed by a dot? RFC 2109 explicitly states that:
The value for the Domain attribute contains no embedded dots or does not start with a dot.
Why? The document indicates that it has to do something with security. I have to admit that I have not read the entire specification (may do it later), but it sounds a bit strange. Based on this, setting cookies on localhost would be impossible.
By design, domain names must have at least two dots; otherwise the browser will consider them invalid. (See reference on http://curl.haxx.se/rfc/cookie_spec.html)
When working on localhost
, the cookie domain must be omitted entirely. Just setting it to ""
or NULL
or FALSE
instead of "localhost"
is not enough.
For PHP, see comments on http://php.net/manual/en/function.setcookie.php#73107.
If working with the Java Servlet API, don't call the cookie.setDomain("...")
method at all.
I broadly agree with @Ralph Buchfelder, but here's some amplification of this, by experiment when trying to replicate a system with several subdomains (such as example.com, fr.example.com, de.example.com) on my local machine (OS X / Apache / Chrome|Firefox).
I've edited /etc/hosts to point some imaginary subdomains at 127.0.0.1:
127.0.0.1 localexample.com
127.0.0.1 fr.localexample.com
127.0.0.1 de.localexample.com
If I am working on fr.localexample.com and I leave the domain parameter out, the cookie is stored correctly for fr.localexample.com, but is not visible in the other subdomains.
If I use a domain of ".localexample.com", the cookie is stored correctly for fr.localexample.com, and is visible in other subdomains.
If I use a domain of "localexample.com", or when I was trying a domain of just "localexample" or "localhost", the cookie was not getting stored.
If I use a domain of "fr.localexample.com" or ".fr.localexample.com", the cookie is stored correctly for fr.localexample.com and is (correctly) invisible in other subdomains.
So the requirement that you need at least two dots in the domain appears to be correct, even though I can't see why it should be.
If anyone wants to try this out, here's some useful code:
<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>
localhost: You can use: domain: ".app.localhost"
and it will work. The 'domain' parameter needs 1 or more dots in the domain name for setting cookies. Then you can have sessions working across localhost subdomains such as: api.app.localhost:3000
.
上一篇: 本地存储vs Cookie
下一篇: 本地主机上带有显式域名的Cookie