HTML return in JS part of response_to block causes errors in IE

Here is a general pattern in my controller actions:

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

Ie, if the request is not AJAX, I will send the HTML content in the layout on the new page. If the request is AJAX, I would send the same content, but without the layout (so that it can be inserted into an existing page or placed in a lightbox or something else).

Therefore, I always return HTML to format.js , but Rails sets the Content-Type response header to text/javascript . This causes IE to throw this fun 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 after_filter or something else), but it looks like I'm trying to do something relatively standard, and I don't want to add additional template code.

How to fix this problem? Alternatively, if the only way to fix the problem is to change the type of response content, which is the best way to achieve the desired behavior (i.e. send content with layout for non-AJAX and the same content without layout for AJAX) without having to deal with by these mistakes?

Edit: There is more information in this blog post

+7
content-type internet-explorer ajax ruby-on-rails
source share
6 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).

Basically, request.xhr? is the key to this decision

+6
source share

The problem is that the response sends the Content-Type header as text/javascript , which then tries to interpret as javascript, which means the missing error message). The server should send the response as type text/html so that the browser does not try to parse and execute the response content as a script, but allows you to use it as an HTML block.

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 can 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 
+1
source share

IE does not understand the answer as HTML. Therefore, either you change the header of the response, or check the change in the request method to GET.

0
source share

If you are trying to send back HTML, you need to do:

 render(:update) do |page| page['someDomId'].replace/replace_html(render(:partial => '/partial/path')) end 

Let PrototypeJS do what it does on the front panel and your DOM identifier will automatically replace its contents. Please note that replace will replace the DOM identifier with this content, replace_html will replace only innerHTML.

0
source share

The root of your problem depends on the method for automatically evaluating the JavaScript response: http://api.prototypejs.org/ajax/ajax/request.html
Your link_to_remote calls generate a js element similar to:

 <a href="#" onclick=" new Ajax.Updater('posts', '/blog/destroy/3', { asynchronous:true, evalScripts:true }); return false; ">Delete this post</a> 

If you don't need to parse the answer anywhere in your application, you can globally redefine the link_to_remote to generate JS without evalScripts:true
If you still need to parse the answer in some parts, create your own link_to_remote_no_eval helper that does not generate JS with evalScripts:true , evalScripts:true .:

 <a href="#" onclick=" new Ajax.Updater('posts', '/blog/destroy/3', { asynchronous:true }); return false; ">Delete this post</a> 

Edit

In this case, why not use a custom content type?

 Mime::Type.register "text/html-piece", :html_piece # add to view in jquery call instead of "text/javascript" # then in your controller action def show respond_to do |format| format.html { } format.html_piece { } # no longer js mime so no IE error end end 
0
source share

in the past, I encountered similar problems with IE. that's how i solved it

 if request.xhr? render 'report', :layout => false else render 'report' end 
0
source share

All Articles