从AJAX POST中,QueryDict总是为空的

13

我看到过一些类似的问题,但是我尝试实施它们的解决方案,却没有成功。

我正在尝试使用POST发送一个基本的AJAX请求到Django视图。以下是我的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) {

        }
    });
});

这是我的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

当我检查Firebug中发生的情况时,我发现我的帖子正在按照我的意愿进行,但是从request.POST中获得的QueryDict对象始终为空。

我认为我已经小心地处理了csrf令牌,甚至尝试在设置中关闭'django.middleware.csrf.CsrfViewMiddleware',但似乎没有效果。

我做错了什么?

感谢您的帮助!


"contentType": "application/json; charset=utf-8" 表示您没有向服务器发送 JSON。此外,应该使用 dataType:'json' 来告诉 success functionresponse 视为可解析的 JSON 对象。至于 Django 响应...请直接访问页面,调试直到获得输出,验证输出确实是 JSON。 - Ohgodwhy
@Ohgodwhy 谢谢您的回复。内容类型只是我试图匹配其他人的代码以解决问题,忘记改回来了。您所说的直接访问页面是什么意思(如果这个问题很蠢,请原谅)? - lac
2个回答

16

Django不会自动反序列化JSON负载。 request.POST 适用于HTML表单等,应该这样使用。

对于JSON负载,您应该自己反序列化请求正文,例如: json.loads(request.body)

request.body是访问原始负载的方式)。


5

正如 @Sergio 提到的那样,你需要在 views.py 中对 request.body 进行解码。这是使用 Django 3.1Fetch 的解决方案。

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)

我不太熟悉AJAX,所以我发布了一个使用 Fetch 典型的带有XHRPOST应该是怎样的。假设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');

下面是使用Fetch执行的实际XHR:
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',
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接