当您使用以下值之一设置 cookie 值时,如中所述Cookie#setValue() https://jakarta.ee/specifications/platform/10/apidocs/jakarta/servlet/http/cookie#setValue(java.lang.String),
对于版本 0 cookie,值不应包含空格、方括号、圆括号、等号、逗号、双引号、斜杠、问号、at 符号、冒号和分号。空值在所有浏览器上的行为方式可能不同。
那么一般容器都会隐式地将cookie设置为版本1(RFC 2109 规范 https://www.ietf.org/rfc/rfc2109.txt) 而不是默认版本 0 (网景规范 https://curl.se/rfc/cookie_spec.html)。该行为不是由 Servlet API 指定的,容器可以自由地实现它(例如,它可能会抛出一些IllegalArgumentException
)。据我所知,Tomcat、JBoss AS 和 Glassfish 在隐式更改 cookie 版本方面的行为完全相同。至少对于 Tomcat 和 JBoss AS 来说,这是修复的结果这个安全问题 https://access.redhat.com/security/cve/CVE-2007-5333.
版本 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。它将把引号解释为整个 cookie 值的一部分,并相应地处理和返回它。它不支持Max-Age
属性,它会完全忽略它,这会导致 cookie 的生命周期默认为浏览器会话。您显然正在使用 IE 来测试您的 web 应用程序的 cookie 处理。
如果您希望支持不支持版本 1 cookie 的浏览器,那么您需要自己对 cookie 值进行 URL 编码和 URL 解码:
Cookie cookie = new Cookie(name, URLEncoder.encode(value, "UTF-8"));
// ...
and
String value = URLDecoder.decode(cookie.getValue(), "UTF-8"));
// ...