Chrome отображает ответ ajax при нажатии кнопки возврата

Я столкнулся с проблемой, заключающейся в том, что если я использую метод Get jQuery для получения некоторого контента, если я щелкаю назад, вместо того, чтобы фактически возвращаться на одну страницу в истории, вместо этого он показывает контент, возвращенный запросом Ajax.

Любые идеи?

http://www.dameallans.co.uk/preview/allanian-society/news/56/Allanian-test

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

Я заметил, что он не всегда это делает, но если вы несколько раз щелкните другую страницу и нажмите кнопку «Назад», он просто отобразит текст json в окне вместо веб-сайта.

По какой-то причине это влияет только на Chrome, поскольку IE и Firefox работают нормально.


person Gavin    schedule 31.03.2012    source источник
comment
вы нашли способ решить эту проблему? У меня такая же проблема.   -  person gabe    schedule 21.05.2012


Ответы (9)


Убедитесь, что в ваших AJAX-запросах используется URL-адрес, отличный от полного HTML-документа. Chrome кэширует самый последний запрос, даже если он частичный.

https://code.google.com/p/chromium/issues/detail?id=108425 < / а>

person abraham    schedule 12.04.2012
comment
Я выдергиваю волосы из-за этого жука уже несколько недель. Спасибо! - person 3urdoch; 09.12.2012
comment
Быстрое решение: добавьте? Ajax = true к своему URL-адресу в запросе ajax. - person Ben Miller; 23.08.2013
comment
На самом деле ответ должен состоять в том, чтобы убедиться, что URL-адрес не кэширован, для чего только одно решение может использовать разные URL-адреса ... - person webjunkie; 25.04.2016
comment
Я не совсем понимаю этот вопрос. С одной стороны, это из-за кеша, а с другой стороны, он не использует кеш. Если бы это было так, это не привело бы к новому ответу. Мое приложение отображает другой ответ для Ajax и другой ответ для не-ajax, а на спине Chrome отображает этот ответ Ajax. Это означает, что он не использует кеш. Смешно, как это вообще кеш связано с Ajax? - person Robo Robok; 29.07.2016

На всякий случай, если вы используете jQuery с History API (или какую-то библиотеку, например history.js), вам следует изменить $ .getJSON на $ .ajax с кешем, установленным на false:

$.ajax({
    dataType: "json",
    url: url,
    cache: false,
    success: function (json) {...}
});
person Dmitrii Sorin    schedule 10.08.2014
comment
Параметр cache: false работает путем добавления отметки времени к URL-адресу, поэтому, если вы используете jQuery, это лучшее решение. Он применяется только к запросам HEAD и GET и устанавливается автоматически, когда dataType равно script или jsonp. - person tombeynon; 25.06.2015

На самом деле это ожидаемое поведение системы кеширования в соответствии со спецификациями, а не проблема хрома. Кэш различает запросы только по URL-адресу и методу запроса (get, post, ...), но не по заголовкам запроса.

Но есть заголовок Vary, который указывает браузеру учитывать некоторые заголовки при проверке кеша. Например, добавив Vary: X-Requested-With к ответу сервера, браузер знает, что этот ответ изменится, если заголовок запроса X-Requested-With изменен. Или, добавив Vary: Content-Type к ответу сервера, браузер знает, что этот ответ изменится, если заголовок запроса Content-Type будет изменен.

Вы можете добавить эту строку в свой роутер для PHP:

header('Vary:X-Requested-With');

И используйте промежуточное ПО в node.js:

app.use(function(req, res) {
    res.header('Vary', 'X-Requested-With');
});
person Ali    schedule 20.02.2016
comment
Работает на меня. У меня должен быть одинаковый URL-адрес для ajax и для классического дохода от панели URL-адресов. Библиотека Ajax, которую я использую, не имеет cache = false .... - person AntiCZ; 24.03.2016
comment
На самом деле это самый элегантный ответ. Спасибо! - person webjunkie; 25.04.2016

Вы также можете добавить случайное значение в конец URL-адреса ajax. Это проигнорирует предыдущий кеш Chrome и запросит новую версию.

url = '/?'+Math.random()
person astroanu    schedule 15.01.2015

Просто добавьте следующий заголовок к заголовкам ответа:

Vary: Accept
person Hamed Kamrava    schedule 14.12.2017

Я не мог указывать разные URL-адреса для каждого запроса ajax, поскольку это была разбивка на страницы, объявление отсутствия кеша в заголовках ничего не дало, поэтому я включил небольшой javascript в представление только тогда, когда заголовки были для запроса ajax:

<script>
if (typeof jQuery == 'undefined') {
    window.location = "<?php echo $this->here; ?>";
}
</script>

Это грязный трюк, но он работает, если содержимое ajax обычно загружается, в контейнер загружен JQuery, поэтому он ничего не делает. Но если вы загружаете предполагаемый контент ajax без окружающего контента, Jquery отсутствует (по крайней мере, в моем случае), поэтому я перенаправляю на текущую страницу, запрашивая обычную страницу GET со всеми заголовками и скриптами.

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

Замени здесь; ?> Судя по текущему URL в вашем приложении, это был CakePhp 2.X

person Gestudio Cloud    schedule 15.11.2013

В 2021 году в Chrome все еще была эта проблема.

Проблема заключается в выполнении базового запроса ajax на тот же URL-адрес, что и тот, на котором в настоящее время находится пользователь. Я работал в Symfony, и полное исправление, которое помогло мне, было

$response->headers->addCacheControlDirective('no-cache', true);
$response->headers->addCacheControlDirective('max-age', 0);
$response->headers->addCacheControlDirective('s-maxage', 0);
$response->headers->addCacheControlDirective('must-revalidate', true);
$response->headers->addCacheControlDirective('no-store', true);

/**
 * from https://stackoverflow.com/a/1975677/5418514
 *
 * The HTTP request header 'Accept' defines the Content-Types a client can process.
 * If you have two copies of the same content at the same URL, differing only in Content-Type,
 * then using Vary: Accept could be appropriate.
 */
$response->headers->set('Vary', 'Accept');
person Julesezaar    schedule 12.01.2021

Ответ @abraham правильный. Я просто хотел опубликовать решение для Rails: все, что вам нужно, это просто добавить другой путь к routes.rb.

Например, у меня есть resource :people, и я хочу составить индексную страницу из частей ajax, одна из которых - список людей. Самый простой способ - создать index.js.erb и частично загрузить через ajax, используя url: people_path. Но здесь возникает проблема.

Итак, для Rails нужно просто добавить другой маршрут, например

get 'people_list', to: 'people#index', as: :people_list, format: :js

person atlascoder    schedule 28.11.2016

Если я хочу использовать метод index контроллера laravel, который возвращает ответ как html, так и json, я добавляю параметр get в конце конечной точки для передачи кеширования браузера:

axios.get(url, {params: {ajax: 1}})
person mcanvar    schedule 13.03.2020