从AJAX POST开始,QueryDict总是空的

lac*_*lac 6 django ajax jquery

我已经看到了一些问题,但我试图实施他们的解决方案,但它对我没用.

我正在尝试使用POST向Django视图发送基本的AJAX请求.这是我的JQuery:

$('#save-button').click(function() {
    var names = ['BLOGGS Joe', 'SMITH John'];
    data = JSON.stringify(names);
    $.ajax({
        "contentType": "application/json; charset=utf-8",
        "data": data,
        "url" : "/ajax/myteam/save/",
        "type": "POST",
        "success": function(response) {

        }
    });
});
Run Code Online (Sandbox Code Playgroud)

这是我的Django视图:

def myteam_save(request):
   if request.method == 'POST':
       if request.POST:
           print 'Hurray'
       else:
           print 'Boo'
       response = HttpResponse(json.dumps({'code':'ok'}), content_type='application/json')
       return response
Run Code Online (Sandbox Code Playgroud)

当我检查Firebug中发生的事情时,我发现帖子正在按照我的意图制作,但来自request.POST的QueryDict对象始终为空.

我一直小心csrf令牌,我想甚至尝试在我的设置中关闭'django.middleware.csrf.CsrfViewMiddleware',但这似乎没有任何效果.

我究竟做错了什么?

谢谢你的帮助!

小智 7

Django并没有JSON为您真正反序列化有效负载.request.POST用于HTML发布表单等.

对于JSON有效负载,您应该自己对请求体进行反序列化,例如:json.loads(request.body).

(request.body是你如何访问原始有效载荷).


Ulv*_*lvi 5

正如@Sergio 所说,您需要解码request.bodyviews.py 中的内容。这是使用Django 3.1和的解决方案Fetch

def myteam_save(request):
    if request.method == 'POST' and request.headers.get("contentType": "application/json"):
        body_unicode = request.body.decode('utf-8')
        received_json = json.loads(body_unicode)

    return JsonResponse(received_json, safe=False)
Run Code Online (Sandbox Code Playgroud)

我不熟悉AJAX。所以我发布了 应该如何典型POSTXHR使用Fetch. 假设varKeyvarValue是预定义变量,其值以 json 形式发送:

根据官方文档,出于安全原因,您必须通过它。

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;
}
const csrftoken = getCookie('csrftoken');
Run Code Online (Sandbox Code Playgroud)

XHR下面是使用实际完成的Fetch

dict = { [varKey]: varValue }

fetch("http://127.0.0.1:8000/bot/api/post/45/", {
    headers: {
        'X-CSRFToken': csrftoken,
        "x-Requested-With": "XMLHttpRequest",
        "Content-Type": "application/json"
    },
    method: 'POST',
    body: JSON.stringify(dict),
    mode: 'same-origin',
})
Run Code Online (Sandbox Code Playgroud)