Почему значения cookie с пробелами поступают на сторону клиента с кавычками? - PullRequest
25 голосов
/ 21 февраля 2009

Я разработчик .NET, начинаю увлекаться Java.

В .NET я могу установить значение cookie для строки с пробелом в ней: new HttpCookie("myCookieName", "my value") - и когда я читаю это значение на стороне клиента (JavaScript), я получаю ожидаемое значение (мое значение).

Если я делаю то же самое в Java-сервлете - new Cookie("myCookieName", "my value"), я получаю значение, включая двойные кавычки («мое значение»).

Почему разница? Я что-то пропустил? Как люди справляются с этим в мире Java? Вы кодируете значение, а затем декодируете на стороне клиента?

Ответы [ 4 ]

42 голосов
/ 29 августа 2011

Когда вы устанавливаете значение cookie с одним из следующих значений, как указано в Cookie#setValue(),

При использовании файлов cookie версии 0 значения не должны содержать пробелов, скобок, скобок, знаков равенства, запятых, двойных кавычек, косой черты, вопросительных знаков, знаков, двоеточий и точек с запятой. Пустые значения могут не работать одинаково во всех браузерах.

тогда средний контейнер будет неявно устанавливать cookie в версию 1 ( RFC 2109 spec ) вместо версии по умолчанию 0 ( Netscape spec ). Поведение не определяется API сервлета, контейнер может свободно его реализовывать (например, он может выдавать IllegalArgumentException). Насколько я знаю, Tomcat, JBoss AS и Glassfish ведут себя одинаково в отношении неявного изменения версии cookie. По крайней мере, для Tomcat и JBoss AS это является следствием исправления этой проблемы безопасности .

Файл cookie версии 1 выглядит следующим образом:

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

в то время как файл cookie, совместимый с версией 0, выглядит следующим образом:

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

(обратите внимание, что значение в кодировке URL действительно для версии 0)

Важное замечание: Microsoft Internet Explorer не поддерживает файлы cookie версии 1. Даже не текущий выпуск IE 11. Он будет интерпретировать кавычки, являющиеся частью всего значения cookie, и будет обрабатывать и возвращать их соответствующим образом. Он не поддерживает атрибут Max-Age и полностью его игнорирует, что приводит к тому, что время жизни куки по умолчанию равно сеансу браузера. Вы, очевидно, использовали IE для проверки обработки файлов cookie вашего веб-приложения.

Для поддержки MSIE вам действительно необходимо URL-кодировать и URL-декодировать значение cookie самостоятельно, если оно содержит символы, которые недопустимы для версии 0.

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

и

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

Чтобы поддерживать файлы cookie версии 1 для мировой аудитории, вам нужно подождать, пока Microsoft исправит недостаток поддержки MSIE, и браузер с исправлением стал основным. Другими словами, это займет возраст (обновление: на данный момент, спустя 5 с лишним лет, похоже, этого никогда не произойдет). В то же время вам лучше всего использовать файлы cookie, совместимые с версией 0.

5 голосов
/ 21 февраля 2009

Насколько я знаю, пробелы должны быть закодированы в куки. Различные браузеры по-разному реагируют на некодированные куки. Вы должны URL-кодировать ваш куки перед установкой.

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

ASP.NET выполняет кодировку автоматически, в Java вы должны сделать это самостоятельно. Я подозреваю, что цитаты, которые вы видите, добавлены пользовательским агентом.

2 голосов
/ 21 февраля 2009

Вероятно, это связано с тем, как Java кодирует куки. Я предлагаю вам попробовать setVersion (1) для нового cookie и посмотреть, работает ли он для вас.

0 голосов
/ 29 августа 2011

Попробуйте использовать setVersion (0).

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

печать:

name = "значение из нескольких слов"

но после настройки

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

печать:

имя = значение из нескольких слов

Кодирование тоже хорошая идея, но кавычки вокруг значения выглядят как самостоятельная проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...