CSRF 令牌丢失或无效。 -> 第一种形式未能通过其他 CSRF 令牌工作

CSRF Token missing or invalid. -> First form fails other CSRF Token work

所以我有一个带有多个按钮的网站。这些按钮在表单内部并使用此 { CSRF }。但是第一个按钮不起作用。

这是 HTML 的片段。

<form  method="post" id="post-form">
                      {% csrf_token %}
                      <button type="submit" name="startVm" class="btn btn-default btn-block d-none d-md-block">StartVM</button>
                </form>
                <form  method="post" id="post-form">
                      {% csrf_token %}
                      <button type="submit" name="stopVm" class="btn btn-default btn-block d-none d-md-block">StopVM</button>
                </form>

这是我使用的 Ajax 函数。

$('#post-form').on('submit', function(e){
        e.preventDefault();
        console.log("form submitted!")  // sanity check
        post();
    });
    // AJAX for posting
    function post() {
        console.log("create post is working!") // sanity check
        $.ajax({
            url : '', // the endpoint
            type : 'post', // http method
            data : {},
            csrfmiddlewaretoken: '{{ csrf_token }}',
            contentType: 'application/x-www-form-urlencoded',
            processData: true,
            // handle a successful response
            success : function() {
               alert("Thank you for your comment!");
                console.log("success"); // another sanity check
            },

            // handle a non-successful response
            error : function(xhr,errmsg,err) {
                $('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
                    " <a href='#' class='close'>&times;</a></div>"); // add the error to the dom
                console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
            }
        });
    };

正如我所说。 StartVM 按钮不起作用,它 returns 出现 403 错误。(禁止(CSRF 令牌丢失或不正确。):/) 但是第二个没有问题。

这是 view.py

中的代码
def post (self, request):
    if request.method == 'POST' and 'startVm' in request.POST:
        print("startVM button")
        return HttpResponse("{}",
        content_type='application/json', status=204)
    if request.method == 'POST' and 'stopVm' in request.POST:
        print("stopVM button");
        return HttpResponse("{}",
        content_type='application/json', status=204)
    return HttpResponse("{}",
    content_type='application/json')

我返回状态 204,因为 e.preventDefault() 不起作用,如果我点击一个按钮,它会刷新整个站点。

首先,id 应该是唯一的,但是您在两个不同的表单上有 id="post-form"

您可以改为 class="post-form",并将您的 JS 更改为使用 .post-form

或者,对于您问题中的模板,您可以有一个包含两个按钮的 <form> 标签。

接下来,您需要在表单数据中包含 CSRF 令牌

data : {'csrfmiddlewaretoken': '{{ csrf_token }}'},

或者,您可以按照文档中的 suggestion,为 ajax 请求添加一个 X-CSRFToken header,这样您就不需要包含post 数据中的令牌。