2009-09-12 13 views
41

Cuando intento para golpear esta acción a través de JavaScript, me sale un error de 406 Not Acceptable:extraño error "406 no es aceptable"

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 

Esto es de jQuery, pero estoy haciendo para la gloria beforeSend:

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

Éstos son mis encabezados de la solicitud:

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 
+1

Por favor marque su respuesta como la correcta ... nunca pensé que agregue un comentario sobre eso, pero hace que encontrar la respuesta sea mucho más fácil. – erroric

+0

Eche un vistazo aquí: http://stackoverflow.com/questions/25910031/jquery-autocomplete-throws-406-not-acceptable-error –

Respuesta

30

¡Rompí la carcasa!

Estaba enviando un parámetro format con mi solicitud get para decirle al servidor que me envíe un descuento en lugar de HTML. Aquí está mi Javascript:

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

y luego yo estaba buscando para este parámetro en el bloque format.js:

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

pero al parecer un parámetro format confunde el bloque respond_to. Lo cambié de {format: 'raw'} a {markdown: 'true'} y funciona.

Supongo que esto es un error en Rails?

+10

Esto no es un error sino el comportamiento previsto: Rails usa los encabezados Accept y el parámetro de formato para determinar si responderán html, javascript, xml, json u otra cosa. Entonces, en su caso, el formato.El bloque js {} nunca se llamó porque Rails pensó que quería algo con el formato "en bruto" y no algo con el formato "js". – severin

+2

Tienes razón: debería haber registrado un mimetype de Markdown (http://stackoverflow.com/questions/2456219/add-a-custom-format-in-rails-that-will-work-with-respond-to) y agregó un bloque 'format.markdown' –

0

Es ésta sirvió través de Apache? Le recomendamos echar un vistazo al http://forums.alwayswebhosting.com/showthread.php?p=8381, que describe situaciones en las que la política de seguridad interfiere con las solicitudes.

EDIT: La URL mencionada anteriormente recomienda desactivar la política de seguridad de detección de solicitudes en todo un sitio, lo que hace que el sitio sea vulnerable. Establecer la opción SecFilterEngine en Off en el .htaccess, que es lo que se prescribe en la URL, debe hacerse solo para concentrarse en el origen del problema. No debe considerarse una solución a largo plazo.

+0

No funcionó <:( –

+0

¿Qué datos quiere enviar de nuevo a el cliente como parte de su respuesta parece? Es JSON, HTML, JavaScript? –

+0

@Horace: por favor, consulte mi actualización a esta publicación. –

0

Si está utilizando jRails esto estaba causando una gran cantidad de problemas para mí, aquí está mi application.js archivo:

$(document).ready(function() { 
    $.ajaxSetup({ 
     beforeSend: function (xhr) { 
      xhr.setRequestHeader("Accept", "text/javascript, text/html, application/xml, text/xml, */*"); 
     } 
    }); 
}); 
+0

No funcionó <:( –

+0

http: // gist. github.com/185743 - Prueba esto r su archivo jRails.js. – Garrett

+0

En realidad, ni siquiera estoy usando jRails (solo jQuery normal) –

2

Se puede tratar sin establecer la cabecera Accept? En realidad, debería funcionar incluso sin el encabezado Aceptar.

+0

Todavía no funciona (¡tan frustrante!) –

0

Para mí, era un before_filter simple que estaba restringiendo una acción que representa un archivo js, ​​una vez que agregué: except => [: action] al bloque before_filter estaba bien.

5

incluyen "format.js" en su bloque respond_to

2

sólo tiene que utilizar este código en el bloque controlador de formato de método de acción:

format.js { render :nothing => true } 
5

Esto me sucedió cuando se utiliza HTTPRiot la conexión a una representación JSON aplicación web desde una aplicación de iPhone. Parece que el problema se debe a que Rails espera un encabezado HTTP Accept con el que se sienta cómodo. Como tal, utilicé la extensión LiveHTTPHeaders de Firefox para ver qué encabezados funcionan sin un 406.En cualquier caso, la cadena Aceptar que trabajó fue:

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 

Otra área que iba a examinar es el controlador JSON productoras. Si al controlador le falta una directiva de formato para especificar que puede devolver JSON en respuesta, eso también puede causar un error 406.

0

Me tocó este problema cuando olvidé agregar :remote => true a mi formulario Ajax.

0

que llamaba la URL para el formato js pero tenía esto en el controlador:

respond_to do |format| 
    format.html 
end 

Esto funcionó bien en Safari, pero no con Firefox.

naturalmente me faltaba algo, debería ser:

respond_to do |format| 
    format.html 
    format.js 
end 

y ahora ambos navegadores están bien.

3

Compruebe sus application.js para requerir jquery_ujs

//= require jquery_ujs 
0

Otra insidiosa "Gotcha" aquí es que si usted llama a su controlador con un form_for que accidentalmente tiene un parámetro de no-necesaria adicional. El parámetro adicional puede ser interpretado por los carriles como una solicitud de formato, y obtendrá el 406.

Ejemplo:

= form_for parking_permit, url: permit_group_parking_permits_path(@permit_group.id, useless_id), method: :get do |f| ...

En el ejemplo anterior, el rastrillo rutas y determinar que hace permit_group_parking_permits_path NO necesita nada, pero la identificación permit_group ...

Si ve que su método se denomina como /model/action.1?blahblahblah que" 0.1" es el chivatazo.

Esto devolverá el 406. No hablaremos de cuánto tiempo pasé en esta vez.