没有 jquery 的 Django CSRF 丢失或不正确的 Ajax POST (Vanilla JavaScript)

Posted

技术标签:

【中文标题】没有 jquery 的 Django CSRF 丢失或不正确的 Ajax POST (Vanilla JavaScript)【英文标题】:Django CSRF missing or incorrect Ajax POST without jquery (Vanilla JavaScript) 【发布时间】:2021-01-19 07:20:33 【问题描述】:

当我在使用 jquery 时遇到此错误时,我很简单:

data: 'csrfmiddlewaretoken': "csrf_token"

现在我正在尝试使用原生 javascript,这是我的 ajax 调用

<script>
    document.addEventListener('DOMContentLoaded', function () 
        document.querySelector('#sendMessage').onclick = function (e) 
            e.preventDefault();
            let xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function (e) 
                if (this.readyState == 4 && this.status == 200) 
                    alert('success')
                    let response = this.responseText
                    console.log(response)
                 else 
                    console.log(this.status)
                    console.log(this.readyState)
                
            ;
            xhr.open("POST", "% url 'chat:room' room.id %", true);
            // Send data csrf_token, content, area
            xhr.setRequestHeader('Content-type', 'application/json');
            data = 
                'csrfmiddlewaretoken': ' csrf_token ',
                'content': document.querySelector('#id_content').value,
                'area': parseInt(document.querySelector('#id_area').value),
            
            console.log(data)
            xhr.send(JSON.stringify(data));
        
    );
</script>

但是我得到了这个错误:

Forbidden (CSRF token missing or incorrect.): /chat/room/3/
[04/Oct/2020 05:25:16] "POST /chat/room/3/ HTTP/1.1" 403 2513

我已经搜索了一段时间,但所有答案都解决了 jquery 而不是 vanilla js,有什么帮助吗?

更新

Views.py:

def room(request, room_id):
    room = get_object_or_404(Room, pk=room_id)
    if request.method == 'GET':
        return render(request, 'chat/room.html', 'room': room)
    else:
        print(request.POST)
        message = Message.objects.create(
            user=request.user, content=request.POST.get('content'), room=room)
        message.save()
    return JsonResponse()

【问题讨论】:

你能在控制台中验证csrf_token并从浏览器的cookie中检查吗? 是的,csrf 令牌没有任何问题,这是我打印数据时得到的结果 csrfmiddlewaretoken: "qYzbJCEZ6LGrhEySpbetbdJlRwdjYrTmtgZ6NV6WKAsJ2R5l3W2Hs3z0LTuSTAQo", ..... 从 django 端检查 csrf 怎么样? 我不知道该怎么做,我唯一尝试的是打印(request.POST),它没有做任何事情,因为我在终端中得到的唯一东西是 CSRF不见了。 为了调试,取消注释所有request.POST 并执行: print(request.POST['csrfmiddlewaretoken'])` 并查看终端。另外,请在帖子中更新您的views.py。这可能会有所帮助。 【参考方案1】:

为 CSRF 设置额外的请求头:

# code

xhr.setRequestHeader('X-CSRFToken', ' csrf_token ');

#code

【讨论】:

以上是关于没有 jquery 的 Django CSRF 丢失或不正确的 Ajax POST (Vanilla JavaScript)的主要内容,如果未能解决你的问题,请参考以下文章

jQuery + AJAX + Django = CSRF ? [复制]

django 1.3 中带有 jquery 和 $.post 的 CSRF

带有 django 的 JQuery AJAX 获取 csrf 错误 403

jQuery AJAX POST 在第一次调用时跳过 Django CSRF 令牌标头

Jquery 和 Django CSRF 令牌

如何将 Django 的 CSRF 令牌添加到 jQuery POST 请求的标头?