views:

2500

answers:

6

When I try to hit this action via Javascript, I get a 406 Not Acceptable error:

  def show
    @annotation = Annotation.find_by_id(params[:id])

    respond_to do |format|
      format.html {
         if @annotation.blank?
           redirect_to root_path
         else
           redirect_to inline_annotation_path(@annotation)
         end
       }

       format.js {
         if params[:format] == "raw"
           render :text => @annotation.body.to_s
         else
           render :text => @annotation.body.to_html
         end
       }
    end
  end

This is from jQuery, but I'm doing the right beforeSend stuff:

  $.ajaxSetup({ 
    beforeSend: function(xhr) {
      xhr.setRequestHeader("Accept", "text/javascript");
    },
    cache: false 
  });

Here are my request headers:

Host    localhost:3000
User-Agent  Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Accept  text/javascript
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive  300
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Content-Type    application/x-www-form-urlencoded
A: 

Is this served through Apache? You may want to take a look at http://forums.alwayswebhosting.com/showthread.php?p=8381, which describes scenarios where security policy interferes with requests.

EDIT: The URL referenced above advocates turning off request-sniffing security policy across an entire site, which makes the site vulnerable. Setting the SecFilterEngine option to Off in the .htaccess, which is what is prescribed in the URL, should be done only to zero in on the source of the problem. It should not be considered a long term solution.

David Andres
Didn't work <:(
Horace Loeb
What does the data you intend to send back to the client as part of your response look like? It is JSON, HTML, JavaScript?
David Andres
@Horace: please see my update to this post.
David Andres
I'm just sending back text (markdown to be precise), although this doesn't work from Javascript even if I comment out the contents of the `format.js` block (so I don't think what I'm sending is relevant). Also, this is happening on my local machine through Mongrel
Horace Loeb
If you aren't sending back javascript, then you don't need the "text/javascript" request header. Perhaps "text/plain" will be a better fit for your needs.
David Andres
A: 

If you are using jRails this was causing a lot of problems for me, here is my application.js file:

$(document).ready(function () {
    $.ajaxSetup({
     beforeSend: function (xhr) {
      xhr.setRequestHeader("Accept", "text/javascript, text/html, application/xml, text/xml, */*");
     }
    });
});
Garrett
Didn't work <:(
Horace Loeb
http://gist.github.com/185743 - Try this for your jRails.js file.
Garrett
I'm actually not even using jRails (just regular jQuery)
Horace Loeb
A: 

Can you try without setting the Accept Header? It should actually work even without the Accept header.

Rishav Rastogi
Still doesn't work (so frustrating!)
Horace Loeb
+1  A: 

I cracked the case!

I was sending a format parameter with my get request in order to tell the server to send me markdown instead of HTML. Here's my Javascript:

$.get("/annotations/" + annotation_id, {format: 'raw'}, function(data) {
});

and then I was looking for this parameter in the format.js block:

   format.js {
     if params[:format] == "raw"
       render :text => @annotation.body.to_s
     else
       render :text => @annotation.body.to_html
     end
   }

but apparently a format parameter confuses the respond_to block. I changed it from {format: 'raw'} to {markdown: 'true'} and it works.

I guess this is a bug in Rails?

Horace Loeb
This is not a bug but intended behaviour: Rails uses the Accept Headers and the format parameter to determine wether to respond with html, javascript, xml, json or something else.So in your case the format.js {} block was never called because Rails thought that you wanted something with the format "raw" and not something with the format "js".
severin
You're right — I should have registered a Markdown mimetype (http://stackoverflow.com/questions/2456219/add-a-custom-format-in-rails-that-will-work-with-respond-to) and added a `format.markdown` block
Horace Loeb
A: 

For me it was a simple before_filter that was restricting a action that renders a js file, once I added the :except => [:action] to the before_filter block it was fine.

Darren
A: 

include "format.js" in your respond_to block

Dustin