2011-05-31 28 views
6

En django 1.3, ahora tiene que usar csrf incluso con ajax. Uso jquery y ahora quiero agregar el token csrf al $ .post. ¿Cómo puedo hacer esto? No soy muy hábil en jquery, así que sería bueno con una buena descripción.

Es una aplicación de calificación y la publicación se envía cuando se hace clic en una estrella. He visto el django docs pero no entiendo qué hacer en mi situación. Mi código está debajo:

$(function() { 
      $("#avg").children().not(":input").hide(); 
      $("#rating-widget").children().not("select").hide();  

      $caption = $("<span/>"); 

      $("#avg").stars({captionEl: $caption}); 
      $("#rating-widget").stars({ 
       inputType: "select", 
       cancelShow: false, 
       captionEl: $caption, 
       callback: function(ui, type, value){ 
-------------->  $.post($("#rating-widget").attr("action"), {score: value}, function(data){ 

        }); 
       } 
      }); 
       $caption.appendTo("#rating-widget"); 

}); 

Se debe decir que el javascript no está en una plantilla, sino en un archivo estático. ¿Sería mejor ponerlo en una plantilla para poder usar {{ csrf_token }}

Gracias de antemano!

Respuesta

7

Coloque este código antes de su función. Se ocupará de CSRF.

$('html').ajaxSend(function(event, xhr, settings) { 
    function getCookie(name) { 
     var cookieValue = null; 
     if (document.cookie && document.cookie != '') { 
      var cookies = document.cookie.split(';'); 
      for (var i = 0; i < cookies.length; i++) { 
       var cookie = jQuery.trim(cookies[i]); 
       // Does this cookie string begin with the name we want? 
       if (cookie.substring(0, name.length + 1) == (name + '=')) { 
        cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
        break; 
       } 
      } 
     } 
     return cookieValue; 
    } 
    if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) { 
     // Only send the token to relative URLs i.e. locally. 
     xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); 
    } 
}); 
+1

Acabo de encontrar una [versión editada] (http://stackoverflow.com/questions/5100539/django -csrf-check-failing-with-an-ajax-post-request) usaron ajaxSetup en su lugar. Funciona para mí :) ¡No sabía que era tan fácil! ¡Gracias! – tmpethick

3

En el django documentation puede encontrar una descripción simple sobre cómo incluir automáticamente el token csrf en cada solicitud de Ajax.

+0

Como dije en la pregunta: Ya revisé ese lugar, pero no pude entenderlo y ponerlo en mi código. Pero gracias de todos modos por el intento de ayudar :) – tmpethick

+0

No funcionó para mí hasta que eliminé las declaraciones if en ajaxSetup, y acaba de tener xhr.setRequestHeader ("X-CSRFToken", csrftoken); – bozdoz

1

¡No tiene que usar un formulario! Simplemente cree una nueva URL que esté vinculada a una función que "marque" publicaciones. Por ejemplo

(r'^myapp/star-post/(?P<post_id>.*)/$','myapp.views.myview') 

Por lo tanto, si envía una solicitud a esa URL, encontrará el cargo en su base de datos, cambie el campo de "Destacados" y devolver una respuesta al Ajax.

Luego puede tener una función de devolución de llamada en caso de éxito que cambiará el CSS en consecuencia (complete la estrella, etc.). De esta manera, no tiene que preocuparse por CSRF.

Pero usted puede preguntar, ¿y qué hay de los ataques de scripting entre sitios! Bueno, si está utilizando la autenticación de usuario con la validación de cookies, ¡no debería tener que preocuparse por eso! Aaay eres bueno para ir.

+0

Esto es exactamente lo que hice. El problema es que tengo que almacenarlo en la base de datos y me pide un token csrf. El problema surgió después de que actualicé fra 1.2 a 1.3 donde tienes tokens csrf, incluso con ajax. Me gustaría saber cómo incluir el token csrf en el envío de la solicitud con ajax – tmpethick

+0

@tmpethick Incluso con el decorador csrf_exempt? de django.views.decorators.csrf import csrf_exempt – systemizer

+0

no he intentado usar ese, pero ahora funciona :) – tmpethick