为什么带有空格的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());
打印:
名称=几个字的值
编码也是一个好主意,但是围绕价值的引用看起来是一个独立的问题。