Ich habe eine Warnung gesetzt, die den Inhalt von druckt getCookie('csrftoken') Vor dem xhr.setRequestHeader Anruf und es ist tatsächlich mit einigen Daten gefüllt. Ich bin mir nicht sicher, wie ich überprüfen kann, ob das Token korrekt ist, aber ich bin ermutigt, dass es etwas findet und sendet.
Aber Django lehnt meinen AJAX-Beitrag immer noch ab.
Hier ist mein JavaScript:
$.post("/memorize/", data, function (result) {
if (result != "failure") {
get_random_card();
}
else {
alert("Failed to save card data.");
}
});
Ich bin sicher, dass ich etwas vermisse, und vielleicht ist es einfach, aber ich weiß nicht, was es ist. Ich habe in SO gesucht und einige Informationen zum Deaktivieren der CSRF-Prüfung für meine Ansicht über die gefunden csrf_exempt Dekorateur, aber das finde ich unattraktiv. Ich habe das ausprobiert und es funktioniert, aber ich möchte lieber, dass mein POST so funktioniert, wie Django es erwartet, wenn möglich.
Nur für den Fall, dass es hilfreich ist, hier ist der Kern dessen, was meine Ansicht tut:
def myview(request):
profile = request.user.profile
if request.method == 'POST':
"""
Process the post...
"""
return HttpResponseRedirect('/memorize/')
else: # request.method == 'GET'
ajax = request.GET.has_key('ajax')
"""
Some irrelevent code...
"""
if ajax:
response = HttpResponse()
profile.get_stack_json(response)
return response
else:
"""
Get data to send along with the content of the page.
"""
return render_to_response('memorize/memorize.html',
""" My data """
context_instance=RequestContext(request))
Danke für eure Antworten!
Welche Django-Version verwendest du?
– zQuadrat
24. Februar 2011 um 7:46 Uhr
Haben Sie die richtigen CSRF-Middleware-Klassen hinzugefügt und in die richtige Reihenfolge gebracht?
– darren
24. Februar 2011 um 7:57 Uhr
Jakub hat meine Frage unten beantwortet, aber nur für den Fall, dass es für andere Leute nützlich ist: @zsquare: Version 1.2.3. @mongoose_za: Ja, sie werden hinzugefügt und in der richtigen Reihenfolge.
– Feuerbusch
26. Februar 2011 um 4:42 Uhr
Bryan
Wenn Sie die verwenden $.ajax Funktion können Sie einfach die hinzufügen csrf Token im Datenkörper:
Wenn ich die markierte Antwort verwende, funktioniert es für mich, aber wenn ich Ihre Lösung hier verwende, funktioniert es nicht. Aber Ihre Lösung sollte funktionieren, ich verstehe nicht, warum es nicht funktioniert. Gibt es noch etwas, das in Django 1.4 getan werden muss?
– Homann
26. Mai 2012 um 23:15 Uhr
Vielen Dank! so einfach. Funktioniert immer noch auf Django 1.8 und Jquery 2.1.3
– Alejandro Veintimilla
21. April 2015 um 19:15 Uhr
Diese Lösung erfordert, dass das Javascript in die Vorlage eingebettet wird, oder?
– Mox
27. Mai 2015 um 6:28 Uhr
@Mox: Fügen Sie dies in HTML ein, aber über Ihrer Js-Datei, wo sich eine Ajax-Funktion befindet <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
– Hier hier
28. Juli 2015 um 14:45 Uhr
Danke, Bro. Dies ist die einfachste und sauberste Lösung. Hat sogar auf Django 3 wie ein Zauber funktioniert.
– Smit Patel
2. September 2020 um 10:53 Uhr
Jakub Gocławski
Echte Lösung
Ok, ich konnte dem Problem auf die Spur kommen. Es liegt im Javascript-Code (wie ich unten vorgeschlagen habe).
Was Sie brauchen, ist dies:
$.ajaxSetup({
beforeSend: function(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'));
}
}
});
Die allgemeine Lösung lautet also: “Verwenden Sie den AjaxSetup-Handler anstelle des AjaxSend-Handlers”. Ich weiß nicht, warum es funktioniert. Aber bei mir funktioniert es 🙂
Vorheriger Beitrag (ohne Antwort)
Ich habe tatsächlich das gleiche Problem.
Es tritt nach dem Update auf Django 1.2.5 auf – es gab keine Fehler mit AJAX-POST-Anforderungen in Django 1.2.4 (AJAX war in keiner Weise geschützt, aber es funktionierte einwandfrei).
Genau wie OP habe ich das in der Django-Dokumentation veröffentlichte JavaScript-Snippet ausprobiert. Ich verwende jQuery 1.5. Ich verwende auch die Middleware “django.middleware.csrf.CsrfViewMiddleware”.
Ich habe versucht, dem Middleware-Code zu folgen, und ich weiß, dass dies fehlschlägt:
Ich hoffe, dass die bereitgestellten Details uns bei der Lösung des Problems helfen werden 🙂
Das hat funktioniert! Ich habe die .ajaxSetup-Funktion so eingefügt, wie Sie sie oben eingefügt haben, und ich kann jetzt ohne 403-Fehler posten. Vielen Dank für das Teilen der Lösung, Jakub. Guter Fund. 🙂
Mit 1.3 hat der offizielle Django-Dokumentationseintrag für mich funktioniert.
– Mönchskutte
15. August 2011 um 14:22 Uhr
Ich habe es versucht, aber das scheint bei mir nicht zu funktionieren, ich verwende jQuery v1.7.2, meine Frage ist stackoverflow.com/questions/11812694/…
– Tagträumer
4. August 2012 um 23:56 Uhr
Ich muss eine Anmerkung hinzufügen @ensure_csrf_cookie um meine Ansichtsfunktion zu erzwingen csrf Cookie, wenn die Seite von mobilen Geräten angefordert wird.
Ich habe das versucht, außer dass mein Formular einen Datei-Upload hat. Mein Backend ist Django und erhalte immer noch Fehler 400 CSRF Failed: CSRF token missing or incorrect.
– Hussain
12. Oktober 2018 um 4:35 Uhr
@Hussain versuchen Sie hinzuzufügen {% csrf_token %} irgendwo in der HTML-Vorlage, auch wenn keine Formular-Tags vorhanden sind. Ohne sie tritt zumindest bei mir der 403-Fehler auf. Siehe: stackoverflow.com/a/65757544/7076615 für weitere Informationen, und ich empfehle auch die Verwendung von X-editable mit Django, es ist ganz nett und in diesem Thread ist ein vollständiges Beispiel.
– Prime-Gap-Homologie-Stoner-Mon.
17. Januar 2021 um 5:12 Uhr
Wie könnten wir dasselbe in Vanilla JavaScript machen?
– Ionekum
29. September 2021 um 3:38 Uhr
Das Problem liegt darin, dass Django erwartet, dass der Wert des Cookies als Teil der Formulardaten zurückgegeben wird. Der Code aus der vorherigen Antwort erhält Javascript, um den Cookie-Wert zu finden und in die Formulardaten einzufügen. Das ist aus technischer Sicht eine schöne Art, es zu tun, aber es sieht ein bisschen ausführlich aus.
In der Vergangenheit habe ich es einfacher gemacht, indem ich das Javascript dazu gebracht habe, den Token-Wert in die Post-Daten einzufügen.
Wenn Sie {% csrf_token %} in Ihrer Vorlage verwenden, wird ein verstecktes Formularfeld ausgegeben, das den Wert trägt. Aber wenn Sie {{ csrf_token }} verwenden, erhalten Sie nur den bloßen Wert des Tokens, sodass Sie dies in Javascript so verwenden können ….
csrf_token = "{{ csrf_token }}";
Dann können Sie das mit dem erforderlichen Schlüsselnamen in den Hash aufnehmen, den Sie dann als Daten an den Ajax-Aufruf senden.
Das {% csrf_token %} Fügen Sie HTML-Vorlagen hinzu <form></form>
und übergeben Sie es dann, indem Sie z. B. einen POST ausführen, wie:
$.post( "/panel/change_password/", {foo: bar, csrfmiddlewaretoken: token}, function(data){
console.log(data);
});
Nicht-jquery-Antwort:
var csrfcookie = function() {
var cookieValue = null,
name="csrftoken";
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
};
Verwendungszweck:
var request = new XMLHttpRequest();
request.open('POST', url, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.setRequestHeader('X-CSRFToken', csrfcookie());
request.onload = callback;
request.send(data);
Alex
Es scheint, dass niemand erwähnt hat, wie man dies in reinem JS mit dem macht X-CSRFToken Kopfzeile u {{ csrf_token }}hier ist also eine einfache Lösung, bei der Sie die Cookies oder das DOM nicht durchsuchen müssen:
var xhttp = new XMLHttpRequest();
xhttp.open("POST", url, true);
xhttp.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
xhttp.send();
10379500cookie-checkDjango CSRF-Prüfung schlägt mit einer Ajax-POST-Anfrage fehlyes
Welche Django-Version verwendest du?
– zQuadrat
24. Februar 2011 um 7:46 Uhr
Haben Sie die richtigen CSRF-Middleware-Klassen hinzugefügt und in die richtige Reihenfolge gebracht?
– darren
24. Februar 2011 um 7:57 Uhr
Jakub hat meine Frage unten beantwortet, aber nur für den Fall, dass es für andere Leute nützlich ist: @zsquare: Version 1.2.3. @mongoose_za: Ja, sie werden hinzugefügt und in der richtigen Reihenfolge.
– Feuerbusch
26. Februar 2011 um 4:42 Uhr