У меня есть файл cookie, который создается из сервлета, и я хотел бы, чтобы он был постоянным, то есть установить cookie, закрыть IE, запустить его резервную копию и по-прежнему иметь возможность читать cookie. Я использую следующий код:
HttpServletResponse response =
(HttpServletResponse) FacesContext.getCurrentInstance()
.getExternalContext().getResponse();
Cookie cookie = new Cookie("someKey", "someValue");
cookie.setMaxAge(7 * 24 * 60 * 60);
response.addCookie(cookie);
Это отлично работает в firefox, но в IE 6/7 cookie не сохраняется между перезапусками браузера. Я проверил все, что могу придумать, в своих настройках, но не могу понять, что может вызвать удаление файла cookie. Насколько мне известно, вызов setMaxAge с положительным числом делает cookie постоянным. Есть идеи, почему это может пойти не так?
Редактировать
Я проверил, используя трюк с дополнительной информацией, предложенный Олафом, что cookie пытается быть установленным как cookie сеанса, а не как постоянный cookie; максимальный возраст установлен на «конец сеанса». Таким образом, не похоже, что для IE устанавливается максимальный возраст - я проверил, что в Firefox максимальный возраст установлен правильно. Я до сих пор не понимаю, что происходит.




Несколько предложений.
Поскольку я не использую окна, это какая-то слабая память: если вы устанавливаете в настройках IE cookie "запрашивать разрешение" каждый раз, когда cookie устанавливается - разве это не показывает, как долго cookie должен быть действителен? Кроме того, вы можете добавить сайт в другую зону безопасности (локальную или как там называлось), чтобы получить совершенно другие настройки и попробовать еще раз.
Надеюсь это поможет...
Я ничего не знаю о Java или сервлетах, но IE будет сохранять файл cookie только в том случае, если он имеет дату истечения срока действия, установки max-age недостаточно, IE продолжит рассматривать его как файл cookie сеанса.
У этого http://www.mail-archive.com/[email protected]/msg52249.html есть ответ, но он не объясняет почему.
То есть, при кодировании @ (который является недопустимым символом в файлах cookie версии 0) cookie, отправленный в ответе, имеет версию, установленную на 0 (приемлемо для IE), а не на 1 (другой формат и, следовательно, неприемлемый IE).
Моя проблема была примерно такой же. Мы использовали кодировку Base64 для нашего значения cookie и отправляли его. Однако Base64 включает такие символы, как '=' ... что снова недопустимо в версии 0 и, следовательно, неприемлемо для IE.
Для меня остается загадка: какая-то часть стека достаточно «умна», чтобы распознать, что значение cookie недействительно как cookie версии 0, и решает отправить ответ как cookie версии 1 (который включает явный номер версии, "недопустимые" символы, поле max-age вместо expires и т. д.) Я не знаю, что именно Tomcat, Faces, Spring или javax.servlet принимает решение перевернуть версию.
Итог: кодирование URI значения cookie гарантирует, что cookie, установленный для браузера, имеет версию 0 и, следовательно, сохраняется в IE.
FWIW, этот blogs.msdn.com/ieinternals/archive/2009/08/20/… очень хорошо объясняет файлы cookie с точки зрения IE ... но я не мог упомянуть об этом в оригинале, так как я новичок и уже включил ссылку.
У меня была аналогичная проблема с IE8, за исключением того, что файл cookie сохранялся при использовании http, но не при использовании https. Решение Intellectual Tortoise сработало для меня, так как у меня там были '=' и другие символы, которые его испортили. До того, как я закодировал файл cookie https, срок его действия был истек в конце сеанса. После кодирования значения срок его действия истек с переданным мной maxAge. Вот методы, которые я использовал для кодирования / декодирования значения cookie перед установкой и после его получения:
public static String encodeString(String s) {
String encodedString = s;
try{
encodedString = URLEncoder.encode(s, "UTF-8");
} catch (UnsupportedEncodingException e) {}
return encodedString;
}
public static String decodeString(String s) {
String decodedString = s;
try{
decodedString = URLDecoder.decode(s, "UTF-8");
} catch (UnsupportedEncodingException e) {}
return decodedString;
}
try{
encodedString = URLEncoder.encode(s, "UTF-8");
} catch (UnsupportedEncodingException e) {}
return encodedString;`a`
}
public static String decodeString(String s) {
String decodedString = s;
try{
decodedString = URLDecoder.decode(s, "UTF-8");
} catch (UnsupportedEncodingException e) {}
return decodedString;
}
Что ж, похоже, что в этом проблема. Глядя на заголовки в Fiddler, Max-Age устанавливается, но не Expires. Я изменил заголовки ответа через Fiddler и добавил свойство Expires, и мой файл cookie был сохранен. Отлично - теперь мне просто нужно найти способ добавить свойство Expires в cookie из Java.