Prototype, Ajax, Firefox, Caching

edit Posted by Felix Morio on Saturday January 05, 2008 at 02:12AM

By default, Ajax.Updater will send a POST request to whatever URL is specified. That's fine, and it prevents certain browser caching issues, but it won't play well with Rails' resource routes. Rails will map POST requests to the create controller action, which is not always desirable.

For example, let's say we have an Ajax.Updater that refreshes a list of posts (GET /posts). Unfortunately, the request that is created by default will be different (POST /posts). You can force the GET method, like so

remote_function(:update => "posts_container", :url => posts_path, :method => :get))

One problem remains, however. If the URL for the remote_function and the URL for the full (html) version of the resource are the same, as they probably ought to be, and if the Ajax call is a GET request, Firefox will cache the data returned by the remote_function call as the most recent version of the page /posts. When a user navigates away from /posts, and subsequently decides to return to /posts by hitting the back button, the remote_function data will be displayed (as opposed to the full html version of the page). That's not very user-friendly.

To avoid this, one will need to set the appropriate header:

headers["Cache-Control"] = "no-store"

Interestingly enough, IE7 appears to deal with this situation correctly.

Comments

  1. oldmoe oldmoe on January 06, 2008 at 10:22PM

    why not solve this problem by adding a format extension to the ajax request? something like : posts.js, or even posts.xhr. This way the urls will not be the same and you still might get some benefit from Firefox caching the Ajax fragment as well (in case you are using Etag or Last-Modified-At HTTP headers for xhr requests as well)

  2. Felix Felix on January 07, 2008 at 05:19AM

    oldmoe: that'd do the trick, as well. I'm just not sure that I like the uri. format. We're requesting the same resource; the only difference is that we want different representations of it. posts.xhr would be a different URI and thus a different resource. That's a bit of REST-nitpicking, so I could live with either solution. Thanks for pointing this out!

  3. oldmoe oldmoe on January 07, 2008 at 04:41PM

    Felix: I am still puzzled by how cache stores should handle different accept headers, be those local browser caches or proxy servers. An extension added to the url is my second best as it is void of all those complexities and can easily be related to the default url (the one without the extension)

  4. Chris Anderson Chris Anderson on January 07, 2008 at 09:05PM

    I'm with oldmoe on this one. I know there are headers and stuff, but there are some serious arguments about making different versions of a resource linkable / bookmarkable / cacheable.

    Servers and software can use headers to distinguish between html, javascript, png, and mp3, but users often want or need the ability to do so using just the URL.

    I may be a heretic, but I see almost nothing compelling about Accepts header content-type negotiation. Seems like more software where we might be better off with less, REST or not.

  5. Alex Chaffee Alex Chaffee on January 09, 2008 at 08:23PM

    Markdown formatting note: if you want to use inner_underscores, make sure to put a backslash in front. You have an outbreak of italicitis starting around remotefunction (presumably remote_function)

Add a Comment (MarkDown available)