0

I have a few actions in my .NET MVC Controller that will return a full view on a regular request, but only a partial if the request is an Ajax request.

At the end of the controller action...

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

On the same controller, I have set some caching options so that one result should be cached for ajax requests, and one for regular requests.

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

Finally, I'm controlling the history using history.pushState and the onpopstate event so that if the user clicks the "back" button, only the part of the page that would change gets reloaded.

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;
        }
    });
});

This works fine, except in Google Chrome. Sometimes, when I navigate to the page by way of the browser's back and forward button, Chrome will inappropriately render the AJAX return value instead of the full page.

So far, this only seems to happen if I use the back/forward buttons to navigate to a different page (either another action on my MVC site, or another site on my domain) and then return to the offending action using the back or forward buttons. Detailed navigation steps:

  1. I load up my site's home page (http://mysite.co).
  2. I click a link on the home page to the controller action that uses all the Ajax/history API magic (http://mysite.co/month/2016/december).
  3. I click a link within that page that triggers an ajax rewrite of the main page content (http://mysite.co/month/2016/january).
  4. I click back (triggers a popstate event, URL changes to http://mysite.co/month/2016/december and AjaxRewrite function gets called).
  5. I click back again (back to http://mysite.co).
  6. I click forward. This returns me to http://mysite.co/month/2016/december, but instead of the full page, I just get the ajax version of the action, which is only a partial view.

Firefox and IE don't have this misbehavior.

Things I've tried to address this:

  1. Specify the output cache location to be the server only. Even after clearing the cache in Chrome, I still get the AJAX version of a page when I ought not.

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

  1. Giving more standard/serializable objects to history.pushState

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

  1. Adding an arbitrary parameter to the ajax request, per HTML5 History API: JSON displayed when going "back" to another page, and then "forward" again.

    $.ajax
    ({
        url: url,
        type: 'GET',
        traditional: true,
        contentType: 'application/json',
        data: {
            //all my normal URL parameters go here
            ajax: "true"
        },
      //.....
    
Community
  • 1
  • 1
jonnybot
  • 2,388
  • 1
  • 27
  • 55

1 Answers1

0

Nevermind! Actually the third thing I tried (adding a dummy parameter to the AJAX requests) did work, but I needed to clear my cache in Chrome before I would see the result.

In short, do this:

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

And then clear your cache in Chrome (Ctrl+Shift+Del for Windows or Shift+Command+Del on a Mac).

jonnybot
  • 2,388
  • 1
  • 27
  • 55
  • This is effectively a duplicate of http://stackoverflow.com/questions/16105242/, but perhaps you can learn from my fail. Or perhaps if you're staring down a similar thicket of layers and red herrings that might be the problem, you'll find the way more easily because of this Q&A. – jonnybot Dec 01 '15 at 17:04