使用 AJAX 时 CSRF 令牌丢失或不正确

问题描述

我已关注 this tutorial 并将我的表单定义如下:

    <form action="" id="contactForm" method="post" role="form" class="contact-form">
    {% csrf_token %}
    ...

views.py:

def contact(request):
    if request.is_ajax():
        sender_name = request.POST.get('sender_name')
        sender_email = request.POST.get('sender_email')
        message_subject = request.POST.get('message_subject')
        message_text = request.POST.get('message_text')

        html_message = render_to_string('contact.html',{'sender_name': sender_name,'sender_email': sender_email,'message_subject': message_subject,'message_text': message_text})

        email_subject = 'Message Subject'
        email_from = 'My Name'
        email_to = ['[email protected]',]

        send_mail(email_subject,'',email_from,email_to,html_message=html_message)

        response = {}

        return JsonResponse(response)

AJAX 代码

$('#contactForm').submit(function(e){
    e.preventDefault()

    $('#loading').css("display","block")

    $.ajax({
        type : "POST",url : "/contact/",data: {
            sender_name : $('#name').val(),sender_email : $('#email').val(),message_subject : $('#subject').val(),message_text : $('#message').val(),csrfmiddlewaretoken : '{{ csrf_token }}',datatype : "json",},success: function(){
            $('#loading').css("display","none"),$('#sent-message').css("display","block")
        },});
});

但是,我在提交表单后收到烦人的“CSRF 令牌丢失或不正确”错误

请帮忙。

编辑:

我将 AJAX 代码从外部 JS 文件移动到 index.html 并且它起作用了!因此,我的 JS 文件似乎无法使用 {% csrf_token %}。为什么会这样以及如何解决

解决方法

你有没有试过像这样附加你的 csrf

要在每个 AJAX 请求中嵌入 csrf 令牌,对于 jQuery,它可能是:

$(function() {

   $.ajaxSetup({
      headers: { "X-CSRFToken": getCookie("csrftoken") }
   });

});
,

根据原始 Django 文档中的 this,您需要将函数 getCokie(name) 实现为:

function getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                const cookie = cookies[i].trim();
                // 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;
    }

然后将标题设置为:

$.ajaxSetup({
   headers:{
      'X-CSRFToken': getCookie("csrftoken")
   }
});

我今天正在实施它,它奏效了,我使用的是 reactJs 并使用 XMLHttpRequest() 发出请求,但它应该非常相似。

,
var el = document.getElementsByName("csrfmiddlewaretoken");
csrf_value = el[0].getAttribute("value");

然后在您的数据中

'csrfmiddlewaretoken' : csrf_value,