.NET MVC Cache, Chrome, действия с переменными результатами и API истории HTML5

У меня есть несколько действий в моем контроллере .NET MVC, которые будут возвращать полное представление по обычному запросу, но только частичное, если запрос является запросом Ajax.

В конце действия контроллера...

    if (HttpContext.Request.IsAjaxRequest())
    {
        return PartialView("_Partial", model);
    }
    else
    {
        return View(model);
    }

На том же контроллере я установил некоторые параметры кэширования, чтобы один результат кэшировался для ajax-запросов, а другой — для обычных запросов.

[OutputCache(Duration = 120, VaryByParam = "*", VaryByHeader="X-Requested-With")]

Наконец, я контролирую историю, используя историю. pushState и событие onpopstate, поэтому что, если пользователь нажимает кнопку «Назад», перезагружается только та часть страницы, которая должна измениться.

jQuery(document).ready(function () {
    if (history.pushState) {
        $(window).on("popstate", function (e) {
            FunctionThatUsesAjaxToRewriteThePage();
        });
    }

    $('#SomeForm').on('submit', function (e) {
        e.preventDefault();
        var url = FunctionToGetUrlToUse();
        if (history.pushState) {
            history.pushState(null, null, url);
            FunctionThatUsesAjaxToRewriteThePage();
        }
        else {
            window.location.href = url;
        }
    });
});

Это отлично работает, кроме Google Chrome. Иногда, когда я перехожу на страницу с помощью кнопки браузера «назад» и «вперед», Chrome неправильно отображает возвращаемое значение AJAX вместо полной страницы.

Пока это происходит только в том случае, если я использую кнопки «назад/вперед» для перехода на другую страницу (либо другое действие на моем сайте MVC, либо на другом сайте в моем домене), а затем возвращаюсь к нарушенному действию с помощью кнопки «назад» или «вперед». кнопки. Подробные шаги навигации:

  1. Я загружаю домашнюю страницу своего сайта (http://mysite.co).
  2. Я нажимаю на главной странице ссылку на действие контроллера, которое использует всю магию Ajax/history API (http://mysite.co/month/2016/december).
  3. Я щелкаю ссылку на этой странице, которая запускает перезапись содержимого главной страницы с помощью ajax (http://mysite.co/month/2016/january).
  4. Я нажимаю назад (вызывает событие popstate, URL-адрес изменяется на http://mysite.co/month/2016/december и вызывается функция AjaxRewrite).
  5. Я снова нажимаю назад (назад к http://mysite.co).
  6. Я нажимаю вперед. Это возвращает меня на http://mysite.co/month/2016/december, но вместо этого полной страницы, я просто получаю ajax-версию действия, которая является лишь частичным представлением.

Firefox и IE не имеют такого неправильного поведения.

Вещи, которые я пытался решить:

  1. Укажите расположение выходного кэша только на сервере. Даже после очистки кеша в Chrome я все равно получаю AJAX-версию страницы, когда не должен.

[OutputCache(Duration = 120, VaryByParam = "*", VaryByHeader="X-Requested-With", Location=OutputCacheLocation.Server)]

  1. Предоставление больше стандартных/сериализуемых объектов для history.pushState

history.pushState({}, '', url); or history.pushState({id: "foo"}, '', url);

  1. Добавление произвольного параметра в запрос ajax для HTML5 History API: JSON отображается при возврате на другую страницу, а затем снова вперед.

    $.ajax
    ({
        url: url,
        type: 'GET',
        traditional: true,
        contentType: 'application/json',
        data: {
            //all my normal URL parameters go here
            ajax: "true"
        },
      //.....
    

person jonnybot    schedule 01.12.2015    source источник


Ответы (1)


Неважно! На самом деле третье, что я пробовал (добавляя фиктивный параметр к запросам AJAX), действительно сработало, но мне нужно было очистить кеш в Chrome, прежде чем я увижу результат.

Короче делай так:

    $.ajax
    ({
        //...
        data: {
            //...your data here
            ajax: "true" //Add this line or one like it to differentiate AJAX requests
        },

И затем очистите кеш в Chrome (Ctrl+Shift+Del для Windows или Shift+Command+Del для Mac).

person jonnybot    schedule 01.12.2015
comment
Фактически это дубликат stackoverflow.com/questions/16105242, но, возможно, вы сможете извлечь уроки из моего провала. Или, возможно, если вы смотрите на похожие заросли слоев и отвлекающих маневров, которые могут быть проблемой, вам будет легче найти путь благодаря этим вопросам и ответам. - person jonnybot; 01.12.2015