从Javascript发送到Django Views的JSON对象为空

时间:2018-11-10 12:13:01

标签: javascript json ajax django

我正在尝试通过ajax将一些数据从Javascript发送到Django。 这是我的JS代码:

            var json_name = {'name': 123}
            $.ajax({
            method: 'POST',
            url: 'my url',
            contentType: "application/json",
            headers: {
                    'Content-Type':'application/json',
                    'X-CSRFToken': "{{ csrf_token }}"
                },

            data: JSON.stringify(json_name),
            success: function (data) {
         //this gets called when server returns an OK response
            alert("it worked!");
            },
        error: function (data) {
             alert("it didnt work");
            }
        });

这是我的Views.py:

def myview(request):
    if request.is_ajax():
       request_data = request.body
       # data = json.loads(request.body)
       print(request_data)
       # print(data)
       return render(request, 'candidate/view.html')
    else:
       return render(request, 'candidate/view.html')

我得到的输出为b''

当我尝试添加以下行时:

data = json.loads(request.body)
print(data)

我收到此错误:

TypeError: the JSON object must be str, not 'bytes'

我参考了here

有人可以帮我吗?如果您需要任何其他信息来解决此问题,我们将很乐意与您分享。

2 个答案:

答案 0 :(得分:0)

掉掉一半的头发后,我通过以下方式解决了问题:

views.py:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def myview(request):
if request.is_ajax():
    if request.method == 'POST':
        data = request.POST.get('senddata')
        print(data)
    return render(request, 'candidate/view.html')
else:
    return render(request, 'candidate/view.html')

我的JS代码:

            <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>

            $.ajax({
            type: 'POST',
            url: 'my url',
            // contentType: "application/json",
            // headers: {
      //               'Content-Type':'application/json',
      //               'X-CSRFToken': "{{ csrf_token }}"
      //           },
            dataType: "json",
            data: {
                senddata: JSON.stringify(json_name),
                },

            // data: json_name,

            success: function (data) {
         //this gets called when server returns an OK response
            alert("it worked!");
            },
        error: function (data) {
             alert("it didnt work");
            }
        });

运行它时,它显示it didnt work,但是我可以在终端中看到输出,即数据已传递。

我尝试在ajax请求中包含csrf令牌,但失败。因此,我在视图中使用了csrf_exempt。

这可能是一种肮脏的做事方式,但目前仍然有效。如果有人有一个更好的答案,请在这里发布!

答案 1 :(得分:-1)

我已经在Django 1.11上使用Python 3.6和Python 2.7编写了一个基本测试用例。

我一直在使用以下模板文件进行测试:

<button>Send data</button>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$('button').on('click', function(event) {
    var data = { name: 123 };
    $.ajax({
        method: 'POST',
        url: '',
        contentType: 'application/json',
        headers: {
            'X-CSRFToken': '{{ csrf_token }}',
        },
        data: JSON.stringify(data),
        success: function() {
            console.log('Success!');
        },
        error: function() {
            console.log('Error...');
        },
    });
});
</script>

以及以下路由,该路由传递模板文件并打印任何AJAX数据:

from django.http import response
from django.shortcuts import render
import json

def index(request):
    if request.is_ajax():
        request_body = request.body
        data = json.loads(request_body)
        print(data)
    return render(request, 'stackoverflowhelp/index.html')

我无法重现该问题。

但是,经过更多研究,我发现Python 3.6中的json.loads方法支持bytes对象,而documentation for Python 2.7 json.loads建议它仅支持字符串类型。尽管您发布的错误反映了这一点,但我试图使它生成与您所看到的相同的错误,但没有成功。

如您所见,我不必将CSRF保护中的方法列入白名单。纯粹基于您提供的错误,可以在decode上调用request.body

def index(request):
    if request.is_ajax():
        request_body = request.body.decode("utf-8")
        data = json.loads(request_body)
        print(data)
    return render(request, 'stackoverflowhelp/index.html')