这是我第一次发布,希望我能正确执行。我花了几天时间在这个问题上,似乎我找不到解决方案。
我需要在提交表单之前将数据添加到表单中。我要添加的数据有点复杂,因此必须放入JSON对象(它包含同一页面上先前绘制的多边形的特征)。
html看起来像这样:
<form id="form-submit-data" action="{% url 'app_name:submit-data' %}" method="POST">
{% csrf_token %}
<input type="text" id="input-value" name="my-value">
<input type="submit" value="Confirm">
</form>
经过几天的挖掘,我决定采用以下实施方式(来自Cory Danielson的回复,并在此处张贴61票: How to trigger an event after using event.preventDefault())。
问题是,如果我在视图函数中添加装饰器@csrf_exempt,则我的表单将被提交两次,一次是使用正确格式设置的数据,一次是这样的“ csrfmiddlewaretoken = 2cYsUn5m50RU1oFwOjPsGpCY5HBelIjQPOOV52KoTpQMWE2zmyIz = value em>:
如果我确实尝试将csrf_token添加到发布请求中(并在我的views函数中注释掉装饰器),我首先会收到“ 禁止(CSRF令牌丢失或不正确。)” 403错误当我刷新时,得到“ 代码400,消息错误的请求语法('{[我的数据格式正确)}} [具有以下形式的页面URL:HTTP / 1.1')”。
(我的浏览器正在接受cookie。我的视图函数将请求传递给模板的render方法,并且我正在使用CsrfViewMiddleware(以回复在调试模式下重定向到的django消息)。
以下是我的jQuery(当我在视图中添加装饰器@csrf_exempt时):
// flag to know if the preprocessing has been done
var preprocessingDone = false;
// stops forms from submitting, adds data previously gathered and resumes submission
$('#form-submit-data').submit(function(event, options) {
options = options || {};
if (!options.preprocessingDone) {
event.preventDefault();
var formData = gatheredData; // from global var
formData["myValue"] = $('#input-value').val();
$.ajax({
//headers: {'X-CSRFToken': '{{ csrf_token }}'},
url: $(this).attr('action'),
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(formData),
dataType: 'text',
success: function(data){
console.log("DATA POSTED SUCCESSFULLY" + data);
},
error: function(jqXhr, textStatus, errorThrown){
console.log(errorThrown);
}
}).then(function() {
// retrigger form submit
$(event.currentTarget).trigger('submit', {'preprocessingDone': true});
});
}
});
(而当我尝试使用csrf_token时,我删除了对ajax调用的headers参数的注释)。
我的理解是,数据提交了两次,一次提交了添加的数据,但是没有csrf_token,一次提交了表单数据,但是没有csrf_token。
我如何将其他数据添加到表单,具有有效的csrf_token并仅提交一次数据?非常感谢您的投入。
PS:我知道从全局变量中获取数据是一种不好的做法,但这就是我经过数天的试验才确定的。我不确定是否可以在原始请求中解决此问题(收集数据),所以我不必在问题中包括它。