在django中发送和接收json请求的正确方法是什么

时间:2016-05-20 07:09:38

标签: json django

有很多关于这个主题的信息,但我仍然不清楚在django中发送和接收json数据的正确方法是什么。是否使用原始格式。

方法1:使用原始格式:

#client
        $.ajax({
            type: "POST",
            url: "api",
            contentType: "application/json; charset=utf-8",
            data: {
                csrfmiddlewaretoken: '{{ csrf_token }}',
                x: $("#x").val(),
            },
            success: response,
            dataType: 'json',
            minLength: 0,
        });

# server - views.py:
@api_view(['GET', 'POST'])
@authentication_classes((TokenAuthentication, SessionAuthentication))
@permission_classes((IsAuthenticated,))
@staff_member_required
def api(request):
    params = request.POST

方法2:使用原始格式:

# client
            $.ajax({
                type: "POST",
                url: "api",
                contentType: "application/json; charset=utf-8",
                headers: {'X-CSRFToken': '{{ csrf_token }}'},
                data: JSON.stringify({
                    x: $("#x").val(),
                }),
                success: response,
                dataType: 'json',
                minLength: 0,
            });

# server - views.py:
@api_view(['GET', 'POST'])
@authentication_classes((TokenAuthentication, SessionAuthentication))
@permission_classes((IsAuthenticated,))
@staff_member_required
def api(request):
    params = json.loads(request.data)

我认为在使用原始格式时,您可以传入列表,但如果没有原始格式,则无法理解数据中的列表。 另一方面,approach2需要JSON.stringify和json.dumps。 此外,我不知道为什么approach2抛出和异常,你无法访问身体... 我想知道的是:

  • 我采取哪种方法是否重要?
  • 如果是这样,哪种方法适当,为什么?
  • 如果原始的json更好,那为什么它会抱怨ajax 请求如下(见下面的错误)?

1 个答案:

答案 0 :(得分:1)

此问题已在django ajax docs上解决:

  

将自定义X-CSRFToken标头设置为CSRF令牌的值。 这通常更容易,因为许多JavaScript框架都提供了允许在每个请求上设置标头的钩子。

请注意,像django-rest-framework这样的流行解决方案正在使用标头方法:

$.ajaxSetup({
  beforeSend: function(xhr, settings) {
    if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
      // Send the token to same-origin, relative URLs only.
      // Send the token only if the method warrants CSRF protection
      // Using the CSRFToken value acquired earlier
      xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
  }
});

django docs建议方法:

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});