为什么带有空格的cookie值到达客户端时带有引号?

我是一个开始涉足Java的.NET开发人员。

在.NET中,我可以将一个cookie的值设置为一个空白string: new HttpCookie("myCookieName", "my value") – 当我在客户端(JavaScript)读取该值时,我期望的价值(我的价值)。

如果我在Java servlet中做同样的事情 – new Cookie("myCookieName", "my value") ,我得到的值包括双引号(“我的价值”)。

为什么区别? 我错过了什么吗? 人们如何在Java世界中处理这个问题? 你编码的价值,然后你在客户端解码?

当您使用Cookie#setValue()提到的以下值之一设置cookie值时,

对于版本0的cookie,值不应包含空格,括号,括号,等号,逗号,双引号,斜杠,问号,符号,冒号和分号。 在所有浏览器上,空值的行为可能不尽相同。

那么平均容器会隐式地将cookie设置为版本1( RFC 2109规范 )而不是默认版本0( Netscape规范 )。 行为不是由Servlet API指定的,容器可以自由地实现它(例如,它可能抛出一些IllegalArgumentException )。 据我所知,Tomcat,JBoss AS和Glassfish在隐式更改cookie版本方面performance完全一样。 对于至lessTomcat和JBoss AS来说,这是修复这个安全问题的结果 。

版本1的cookie看起来像这样:

  name =“value with spaces”; Max-Age = 3600; Path = /; Version = 1 

而与版本0兼容的cookie看起来像这样:

  name = value%20with%20spaces; Expires = Mon,29-Aug-2011 14:30:00 GMT; Path = / 

(请注意,URL编码值对版本0有效)

重要说明是Microsoft Internet Explorer不支持版本1 cookie。 即使不是目前的IE 11版本。 它将解释引用是整个cookie值的一部分,并将相应地处理和返回。 它不支持Max-Age属性,它会完全忽略它,导致cookie的生命周期默认为浏览器会话。 你显然是使用IE来testing你的web应用程序的cookie处理。

为了支持MSIE,如果它包含的可能字符对于版本0是无效的,那么你确实需要自己对cookie值进行URL编码和URL解码。

 Cookie cookie = new Cookie(name, URLEncoder.encode(value, "UTF-8")); // ... 

 String value = URLDecoder.decode(cookie.getValue(), "UTF-8")); // ... 

为了支持全球受众的版本1cookies,你真的会等待微软解决缺lessMSIE支持的问题,并且修复后的浏览器已经成为主stream。 换句话说,这将需要很长时间 (更新:现在,5年以后,似乎不会发生)。 与此同时,你最好坚持版本0兼容cookies。

据我所知,空格必须用cookies编码。 不同的浏览器对未编码的cookies有不同的反应。 设置之前,您应该对您的Cookie进行url编码。

 String cookieval = "my value"; String cookieenc = URLEncoder.encode(cookieval, "UTF-8"); res.addCookie(new Cookie("myCookieName", cookieenc)); 

ASP.NET自动进行编码,在Java中你必须自己做。 我怀疑你看到的报价是由用户代理添加的。

这可能与Java编码cookie的方式有关。 我build议你尝试在新的cookie上调用setVersion(1) ,看看是否适合你。

尝试使用setVersion(0)。

 HttpCookie cookie = new HttpCookie("name", "multi word value"); System.out.println(cookie.toString()); 

打印:

名称=“几个字值”

但设定后

 cookie.setVersion(0); System.out.println(cookie.toString()); 

打印:

名称=几个字的值

编码也是一个好主意,但是围绕价值的引用看起来是一个独立的问题。