Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning HTML in the JS portion of a respond_to block throws errors in IE

Here's a common pattern in my controller actions:

respond_to do |format|
  format.html {}
  format.js {
    render :layout => false
  }
end

I.e., if the request is non-AJAX, I'll send the HTML content in a layout on a brand new page. If the request is AJAX, I'll send down the same content, but without a layout (so that it can be inserted into the existing page or put into a lightbox or whatever).

So I'm always returning HTML in the format.js portion, yet Rails sets the Content-Type response header to text/javascript. This causes IE to throw this fun little error message:

alt text http://dl.dropbox.com/u/2792776/screenshots/Screen%20shot%202010-02-25%20at%205.13.49%20PM.png

Of course I could set the content-type of the response every time I did this (or use an after_filter or whatever), but it seems like I'm trying to do something relatively standard and I don't want to add additional boilerplate code.

How do I fix this problem? Alternatively, if the only way to fix the problem is to change the content-type of the response, what's the best way to achieve the behavior I want (i.e., sending down content with layout for non-AJAX and the same content without a layout for AJAX) without having to deal with these errors?

Edit: This blog post has some more info

like image 431
Tom Lehman Avatar asked Feb 25 '10 22:02

Tom Lehman


2 Answers

Does this work for you?

respond_to do |format|
  format.html { :layout => false if request.xhr? }
  format.js {}
end

And then call the response as HTML, not JS (I have not tested it though.)

Basically, request.xhr? is the key for this solution

like image 60
Ram on Rails React Native Avatar answered Nov 13 '22 02:11

Ram on Rails React Native


The problem is that the response is sending the Content-Type header as text/javascript which IE then tries to interpret as javascript, hence the missing ')' error message. You need the server to send response as type text/html so that the browser will not attempt to parse and execute the response content as a script but will allow you to use it as a block of HTML.

You can do this in Rails by adding something like the following to one of your controllers:

@headers["Content-Type"] = "text/html"

For example, you might add this to your Application Controller as follows:

class ApplicationController < ActionController::Base
  before_filter :fix_ct
  def fix_ct
    @headers["Content-Type"] = "text/html" 
  end    
end
like image 45
defines Avatar answered Nov 13 '22 02:11

defines