有很多关于这个主题的信息,但我仍然不清楚在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抛出和异常,你无法访问身体... 我想知道的是:
答案 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);
}
}
});