Постоянные файлы cookie из сервлета в IE

У меня есть файл 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 максимальный возраст установлен правильно. Я до сих пор не понимаю, что происходит.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
0
9 916
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Несколько предложений.

  1. Вы используете fqdn для доступа к сайту?
  2. используйте скрипач, чтобы проверить, как файл cookie выглядит в ответе http.
  3. Убедитесь, что другие сайты в Интернете успешно сохраняют файлы cookie.

Поскольку я не использую окна, это какая-то слабая память: если вы устанавливаете в настройках IE cookie "запрашивать разрешение" каждый раз, когда cookie устанавливается - разве это не показывает, как долго cookie должен быть действителен? Кроме того, вы можете добавить сайт в другую зону безопасности (локальную или как там называлось), чтобы получить совершенно другие настройки и попробовать еще раз.

Надеюсь это поможет...

Ответ принят как подходящий

Я ничего не знаю о Java или сервлетах, но IE будет сохранять файл cookie только в том случае, если он имеет дату истечения срока действия, установки max-age недостаточно, IE продолжит рассматривать его как файл cookie сеанса.

Что ж, похоже, что в этом проблема. Глядя на заголовки в Fiddler, Max-Age устанавливается, но не Expires. Я изменил заголовки ответа через Fiddler и добавил свойство Expires, и мой файл cookie был сохранен. Отлично - теперь мне просто нужно найти способ добавить свойство Expires в cookie из Java.

Matt McMinn 27.07.2009 22:39

У этого 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 ... но я не мог упомянуть об этом в оригинале, так как я новичок и уже включил ссылку.

Jacob Zwiers 10.12.2009 17:39

У меня была аналогичная проблема с 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;
}

Другие вопросы по теме