在Django后端,FormData()对象始终为空
FormData() object is always empty in Django backend
我正试图通过AJAX上传一个HTML表单(只有JS,没有jQuery)。该表单是由我的模板通过添加三个组件组装而成的:csrf令牌、ModelForm和常规Django表单(forms.form)。模型表单{{form.as_p}}包含表单的可见部分,而表单{{order_form}}包含一些隐藏字段。我的模板的表单部分如下所示:
<form id="{{ form_id }}" action="javascript:submitThisForm('{{ form_id }}', '/submit_blog_entry/')" method='POST' enctype='multipart/form-data'>
{% csrf_token %}
{{ form.as_p }}
{{ other_form }}
<input type='submit' value='SAVE changes' />
</form>
我已经尝试从<form>
标记中删除enctype(我在回复另一个问题时读到FormData()自动添加了这个),但没有成功。
当按下提交按钮时,将调用JS函数submitBlodEntryForm(),传递用于AJAX请求的表单ID和url。JS函数的代码在这里:
function submitThisForm(form_ID, url){
var submit_form = document.getElementById(form_ID);
var formData = new FormData(document.getElementById(form_ID));
httpRequest = new XMLHttpRequest();
if (!httpRequest){
alert("Giving up, cannot create an XMLHTTP instance.");
return false;
};
var url = "/submit_blog_entry/";
var sendCSRFtoken = "csrfmiddlewaretoken="+String(getCookie('csrftoken'));
var sendContent = sendCSRFtoken+"&"+formData;
httpRequest.onreadystatechange = alertContents;
httpRequest.open('POST', url, true);
httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//httpRequest.send();
httpRequest.send(sendContent);
// alternatively: httpRequest.send(formData);
}
AJAX请求被提交到服务器并由服务器接收(Django视图)。如果我没有手动添加上面JS代码中所示的csrf令牌(变量sendContent),只发送formData,我会收到403错误,显然是因为服务器找不到令牌。它应该是形式的一部分,不过。。。
当我尝试将收到的数据绑定到相应的表单时,验证失败:
form = ThisForm(request.POST)
if form.is_valid():
#do something
如果我打印所需内容。POST,我在终端中得到以下内容:
<QueryDict: {'[object FormData]': [''], 'csrfmiddlewaretoken': ['token goes here']}>
显然,FormData对象是空的。我之所以这么认为,是因为我的表单中的两个必填字段(通过使用form.errors.as_data())出现了以下两个错误:
[ValidationError(['This field is required.'])]
出了什么问题?我是否把模板搞砸了,以至于FormData()无法生成有用的数据?我是否错误地创建了AJAX请求?还是服务器端的问题(尽管到目前为止我几乎没有在那里做任何事情)?
谢谢你,非常感谢你的帮助!
最好不要像这样将表单元素传递给FormData:
new FormData(document.getElementById(form_ID))
我几乎可以肯定,它只有firefox支持。其他浏览器不会自动填充对象。
还有你做的:
var sendContent = sendCSRFtoken+"&"+formData;
由于"sendCSRFtoken"是一个字符串,它调用formData上的toString()方法并将两者连接起来,这就是为什么在django端获得"[object formData]"的原因。
使这项工作添加表单字段的一种方法是:
formData.append(name, value);
对CRSF令牌执行同样的操作,然后调用send,如下所示:
httpRequest.send(formData);
XMLHttpRequest有多个用于发送的重载,因此如果您愿意,也可以发送编码字符串:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#send()
在调试时,在ajax调用之前在chrome开发工具中打开网络选项卡,以验证发布的内容是否正确,然后再排除客户端,这将非常有帮助。
感谢大家。我现在发现了问题,愚蠢的复制&粘贴创建AJAX请求的JS函数submitBlogEntryForm()不正确。设置httpRequest标头
httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
导致与编码指令相矛盾。我只是完全删除了这一行,也没有在模板的表单标记中指定"enctype",而是让FormData()自动设置所有这些。现在它工作了!
再次感谢您的帮助!
有2个问题
- 您必须使用FormData.append将数据添加到使用FormData的请求中
- FormData对象在请求中使用多部分/表单数据内容类型(该类型是自动正确设置的)
...
var url = "/submit_blog_entry/";
formData.append("csrfmiddlewaretoken",getCookie('csrftoken'));
httpRequest.onreadystatechange = alertContents;
httpRequest.open('POST', url, true);
//httpRequest.send();
httpRequest.send(formData);
...
- 在模板中为Django表单分离媒体类对象的JS和CSS列表输出
- 通过AJAX调用将JSON对象发送到Django后端
- 在Django后端,FormData()对象始终为空
- 在 django 中接收嵌套的 JSON 对象
- Django 无法在视图中创建常规对象,返回 500 错误
- 使用 jQuery 选择 Django 对象
- 在 Django 视图中检索嵌套的 JavaScript 对象作为字典
- Django -- 为数据库对象的网页生成 URL
- Django:从QueryDict读取JSON对象数组
- 如何访问django中的itertools对象
- 编码对象的Django模板变量查找
- 从python中检索json对象(使用Django)-Javascript
- 无法从jQuery检索发布到Django的对象数组
- Django:防止重复对象创建的策略
- Django Rest框架:在JSON对象内循环
- 通过Django模板变量将Python对象传递给JavaScript
- 从服务器端Python获取JSON对象到客户端Django模板
- 序列化Django URL的JSON对象
- 通过Django模板将对象传递给javascript
- 从JSON序列化的django对象访问字段值