Подтвердить что ты не робот

Как правильно предотвратить кеширование адреса перенаправления 302?

Я столкнулся с следующей проблемой с шаблоном Post/Redirect/Get. При выполнении GET после перенаправления Chrome берет страницу из кеша. Таким образом, пользователь видит устаревшие данные.

302 chrome from cache

Я пробовал следовать для подтверждения/поддержки повторной аттестации

if (request.checkNotModified(sinceLastTweet)) return null;
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Last-Modified", String.valueOf(sinceLastTweet));

Но только no-store вызывает запрос сервера.

Почему Chrome берет страницу из кеша при выполнении перенаправления?


введите описание изображения здесь

@RequestMapping(method = GET)
public String home(ModelMap model, @PathVariable String username, HttpServletResponse response, WebRequest request) {
    // response.setHeader("Cache-Control", "no-store");

    List<Tweet> tweets = tweetRepository.findAll();
    // long sinceLastTweet = tweets.get(0).getTimestamp().toEpochMilli();
    // if (request.checkNotModified(sinceLastTweet)) return null;
    // response.setHeader("Cache-Control", "no-cache");
    // response.setHeader("Last-Modified", String.valueOf(sinceLastTweet));

    model.addAttribute("tweets", tweets);
    model.addAttribute("tweet", new Tweet());
    model.addAttribute("username", username);

    return "home";
}
4b9b3361

Ответ 1

Если один экземпляр Chrome имеет кэшированную страницу /username, страница не попадает в этот Chrome как эффект перенаправления, потому что Chrome читает заголовок Location и обслуживает кэшированную страницу.

Возможно, когда-нибудь вы посетили страницу во время проверки заголовков кеша, и теперь ваш Chrome считает, что он должен кэшировать ее, возможно, даже навсегда.

Вам нужно сделать недействительным кеш (с этим Chrome) для страницы /username:

  • настройте страницу /username как всегда, обслуживаемую заголовками, которые отключают кеширование, например те, которые предлагаются rev_dihazum или как это делается в Spring WebContentGenerator.
  • Очистите кеш вручную или посетите /username и нажмите CTRL + R, находясь на странице: страница будет запрошена, заголовки кэширования будут прочитаны, и с этого момента страница будет снова запрашиваться на сервере, в том числе когда запрашивается как эффект перенаправления.

Если страница является общедоступной и пользователи, браузеры которой вы не можете контролировать, уже кэшировали ее, тогда проблема хуже, и вы можете выбрать одно из следующих значений:

  • Ожидание истечения срока действия кэша
  • измените имя на страницу
  • добавьте случайное число, более или менее, как было предложено prad121, на URL Location, чтобы сделать его уникальным, вариант 2)

Обратите внимание, что Last-Modified формат времени Tue, 15 Nov 1994 08:12:31 GMT, вы можете использовать метод setDateHeader, чтобы установить его как long

Вы можете посмотреть WebContentGenerator, чтобы увидеть другой код кеширования в Spring.

Ответ 2

1) Вы должны попытаться заставить Chrome не использовать кеш,

Как управлять кэшированием веб-страниц во всех браузерах?

Как и ответ на этот вопрос, вы должны поместить этот заголовок в ответ http:

response.header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.header("Pragma: no-cache"); // HTTP 1.0.
response.header("Expires: 0"); // Proxies.

2) Вы можете сделать небольшой трюк

Вы можете запрограммировать, чтобы ответить на любой запрос следующим форматом с помощью того же контроллера:

http://localhost:8080/spitter/username-{timestamp}

Затем вы меняете свои ссылки на своей странице, чтобы иметь последнюю метку времени перед отправкой запроса.

В этом случае событие, если хром кэширует страницу, не имеет значения.

Вместо метки времени вы можете использовать любую другую методологию, например "автоинкремент" или "uuid".

Ответ 3

Возможно, вы можете попробовать использовать ETag для своей страницы.

Я не совсем уверен, правильно ли понимаю ваш сценарий перенаправления.

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

Один из вариантов - включить username в URL-адрес (например, ...&username=Jack). Поскольку имя пользователя изменилось, URL-адрес также изменится (т.е. ...&username=Jim). В этом случае Chrome не будет иметь кэшированную версию отображаемой страницы для Jack и получит новую версию с сервера. (Если у вас есть какое-либо поле, которое вы не хотите явно указывать в URL-адресе, вы можете рассчитать контрольную сумму по всем полям и добавить это как параметр, например ...&check=12345678).

Другим вариантом будет создание сервера ETag, поэтому рассмотрим это подробно. Мы хотим, чтобы серверное приложение отвечало за просмотр браузера, если данные нуждаются в обновлении или могут быть взяты из кэша, правильно?

Использование Etag для того, чтобы сервер мог определить, соответствуют ли данные актуальным или нуждаются в обновлении

{Пожалуйста, простите меня, что я не использую ваш пример здесь, так как я сейчас разрабатываю другой стежок. Однако, я думаю, ваша проблема может быть решена с помощью вашего Java/ Spring Stack таким же образом}

Взгляните на скриншот в разделе Заголовки ответов, а в середине вы увидите ETag. Этот идентификатор генерируется сервером, поэтому здесь используется серверное приложение. (Возможно, эта статья поможет вам, если вы еще не реализовали ETag.)

Так что же происходит? Как только содержимое изменяется на сервере, меняется и ETag - браузер видит ETag в ответе, уважает, что сервер отвечает, и спрашивает сервер, изменился ли контент и если он выкинул кэшированную страницу с помощью истекшего содержимого и запрашивает новый с сервера.

Вы должны убедиться, конечно, что, как только сервер узнает, что пользователь изменил с Джека на Jim (или любое другое поле соответственно), серверное приложение генерирует новый ETag для этой пользовательской страницы отображения.

Надеюсь, что это поможет!

Ответ 4

Добавьте некоторые случайные числа (текущее время в milisecs) в конце URL-адреса. как URL-адрес службы

http://localhost:7001/rest/getBook/5

Таким образом, вместо того, чтобы звонить по указанному выше URL-адресу, добавьте некоторые случайные числа в конце при выполнении вышеуказанного служебного вызова

/rest/getBook/5?_time-in-milisec

В javascript требуется мало настраивать вызов службы.

URL = http://localhost:7001/rest/getBook/5 + "?_" +new Date()

Поскольку каждый раз URL-адрес отличается, он не относится к кешу браузера.

Ответ 5

Вы можете использовать POST вместо GET. POST не кэшируются.