16

我使用文档getCookie中的函数来获取值。djangocsrfmiddlewaretoken

我有以下ajax调用:

var url = reverse_removeprofile.replace(/deadbeef/, key);
$.ajax({
    type:          "DELETE",
    url:           url,
    data:          "csrfmiddlewaretoken=" + getCookie("csrftoken"),
    success:       function() { ... },
});

执行此代码时,会django引发 403 异常,告诉我 CSRF 验证失败。但是,如果我将typefrom更改DELETEPOSTthendjango就会对此感到高兴并且根本不会抱怨。

我真的无法在谷歌中找到有用的东西,但我发现了这张(现已关闭并修复)票:https ://code.djangoproject.com/ticket/15258

如果我理解正确,则此问题已在 1.4 里程碑中得到修复。我使用 django 1.4,但仍然无法通过DELETE请求验证 CSRF 令牌。

我在这里错过了什么吗?

4

2 回答 2

40

这似乎是一个 jQuery 错误,原因是关于 DELETE 数据是否应该附加到 URL(如 GET 请求)或请求正文(如 POST)的一些混淆

请参阅此错误报告

您可能可以通过使用 AJAX 调用的替代 CSRF 方法来解决此问题,X-CSRFToken在请求上设置标头。尝试将您的 AJAX 调用更改为如下所示:

$.ajax({
    type: "DELETE",
    url: url,
    beforeSend: function(xhr) {
        xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
    },
    success: function() { ... },
});
于 2012-10-26T15:38:03.860 回答
0

请注意,当涉及到DELETE请求时,DJango 不会csrfmiddlewaretoken在请求正文中进行检查。而是寻找X-CSRFToken标题

开始 DJango CSRFMiddleware 的工作,您可以看到源代码,django > middleware > csrf.py > CsrfViewMiddleware其中很明显,csrfmiddlewaretoken如果请求类型为 DJango 不会在请求正文中扫描DELETE

        # Check non-cookie token for match.
        request_csrf_token = ""
        if request.method == "POST":
            try:
                request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
            except OSError:
                # Handle a broken connection before we've completed reading
                # the POST data. process_view shouldn't raise any
                # exceptions, so we'll ignore and serve the user a 403
                # (assuming they're still listening, which they probably
                # aren't because of the error).
                pass

        if request_csrf_token == "":
            # Fall back to X-CSRFToken, to make things easier for AJAX,
            # and possible for PUT/DELETE.
            request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')
于 2021-11-29T17:29:05.163 回答