Request.xhr? is false after redirecting an AJAX request?

Dear everybody

I’m trying to develop a web application that makes use of AJAX, but also
works
if a user has no (or doesn’t want to use) JS. For normal requests, this
is
pretty easy. Almost every action ends with
render blahblah, :layout => !request.xhr?
This way, I can use the same action to render a full page (with layout)
as
well as rendering an AJAX request (only the div, no layout)

The problem occurs when doing a redirect_to in an AJAX request (e.g. if
a form
post request was successful and the user is redirected to the list
action).
The AJAX request is properly redirected and the browser requests the new
action… But the new action doesn’t recognize the request as AJAX
(request.xhr? returns false), so that (in my case) it renders the full
page
where it should only render a single div.

Is this a bug or is the behaviour of request.xhr? undetermined after a
redirect? Could this be browser-specific? (I’m using FF 1.5 for
development).
What would be the proper way to handle this case?

PS: Of course I could use the flash to set a flag that remembers a
redirected
AJAX call - but that would just be a workaround :-/

regards,
Andreas Neuhaus

Hey Andreas - The redirect is performed by the browser (as instructed
by the server) by http status code 301 (I think).

Thus the redirect would likely appear be a GET.

You could simulate your requirements by rendering RJS - that could
call an ajax updater.

Cheers, J

Hey Andreas - The redirect is performed by the browser (as instructed
by the server) by http status code 301 (I think).
Thus the redirect would likely appear be a GET.

I investigated the request/response between Firefox and Webrick and
found out
the following:

  • Client: if the user clicks an AJAX link, prototype generates a http
    POST
    request to the given url. This request contains a X-Requested-With:
    XMLHttpRequest header (and an X-Prototype-Version header).
  • Server: The action is called and request.xhr? is true. The request is
    identified as an XHR request because of the X-Requested-With header (I
    suppose).
  • Server: Sends back th response: A 302 redirect to another url
  • Client: Firefox recognizes the 302 response and starts a new GET
    request to
    get the page it was redirected to. This request unfortunately does not
    contain a X-Requested-With header
  • Server: The action is called and request.xhr? is false because there’s
    no
    X-Requested-With header
  • Server: Sends back a full page (with layout etc)
  • Client: Prototype receives the response of its AJAX request and puts
    the
    result in the :update-element (a div)

The result is a messed up layout because a whole page is shown inside a
div
which should only contain some small text.

regards,
Andreas Neuhaus

Ajax calls do not respond to 302 returns, if you want an ajax call toi
redirect you must use
something like this in the controller…

     render :update do |page|
           page.redirect_to( :action => 'redirect_action')
     end

This generates a javascript redirect that an Ajax call will respond to.