Django rest api使用JavaScript客户端导致post请求上的csrf问题

Django rest api using javascript client causing csrf issues on post requests

本文关键字:请求 post 问题 csrf api rest 使用 JavaScript 客户端 Django      更新时间:2023-09-26

我正在使用这个和这个在我的休息 API 上发布一些数据。但是我收到一个错误的请求 (400( 响应。

我的一段代码

var dataTask = {};
var dataPeri = {};
var csrf;
var that = this;
var date = new Date();
var dateString;
dateString = date.toJSON().slice(0, 10);
dataPeri['date'] = dateString;
dataPeri['customer'] = customerId;
csrf = $('input[name="csrfmiddlewaretoken"]').val();
console.log('csrf:'+csrf);
console.log(dataPeri); //The objects seems fine with date at the right format and customerId a number
$.ajaxSetup({
   beforeSend: function(xhr, settings){
       if (!this.crossDomain){
           xhr.setRequestHeader("X-CSRFToken", csrf);
       }
   }
});
$.ajax({
    dataType:'json',
    type: 'post',
    url: '/crm/api/periodontogramms/',
    data:JSON.stringify(dataPeri),
    success: function (data, textStatus, jqXHR){
        alert("New Periodontogramm saved successfully");
        console.log("Periodontogramma "+ data);
        that.periodontogramms.push(data);
    },
    error: function (jqXHR, textStatus, errorThrown){
        alert(errorThrown);
    }
});

我无法理解错误是什么,因为错误没有其他消息。我要把杰森送回去。(使用 JSON.stringify(。我应该发送其他东西吗?可能是日期字符串导致了问题吗?在我的可浏览 API 上发布我使用以下格式使用日期的内容:YYY-MM-DD .这就是我从date.toJSON.slice(0, 10)得到的.如果是csrf问题,我不应该收到禁止的消息(403(

这最初是由@Apostolos回答

的问题

在我删除JSON.stringify并发送普通javascript ojbect之后,它起作用了。

但是没有解释为什么。问题是您将 JSON 数据(用 JSON.stringify 编码(作为字符串发送到 API,但 API 的印象是您正在发送表单编码的数据。

您在$.ajax()调用中使用了一些参数,但缺少一些重要的参数。

dataType 参数根据正在发送的 Accept 标头告诉 jQuery 期望返回的数据类型。在大多数情况下,这是json的,默认情况下,jQuery将根据响应的内容进行智能猜测。这通常是对的,但帮助它并没有什么坏处。

contentType参数告诉jQuery发送到服务器的数据类型。默认情况下,这是 application/x-www-form-urlencoded; charset=UTF-8发送 JSON 数据时,必须将其设置为 application/json 。这很重要,否则 jQuery 将不知道如何处理您提供给它的 JSON 字符串,并且 API 将不知道如何处理格式错误的表单编码数据。

data参数告诉 jQuery 要发送到服务器的数据。使用默认contentType,这将接受表单编码的字符串或包含应进行表单编码的键 -> 值对的字典。当contentType被覆盖时,jQuery期望此处发送的数据应该与必须发送到服务器的数据完全匹配,在您的情况下是JSON字符串。


我还建议您使用浏览器的开发人员工具来阅读响应的正文,因为这应该告诉您发送的请求存在问题。