[英]FormData() object is always empty in Django backend
我正在尝试通过AJAX(只是JS,没有jQuery)上传HTML表单。 通过添加三个组件,该模板由我的模板组装而成: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(),传递表单ID和用于AJAX请求的网址。 该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
如果我打印出request.POST中的内容,则会在终端机中得到以下内容:
<QueryDict: {'[object FormData]': [''], 'csrfmiddlewaretoken': ['token goes here']}>
显然,FormData对象为空。 我也假设这是因为我在表单中的两个必填字段(通过使用form.errors.as_data())得到了以下两个错误:
[ValidationError(['This field is required.'])]
怎么了? 我是否弄乱了模板,使FormData()无法产生有用的数据? 我是否错误地创建了AJAX请求? 还是服务器端的问题(尽管到目前为止我几乎没有做任何事情)?
谢谢您的任何帮助,不胜感激!
你有两个问题
...
var url = "/submit_blog_entry/";
formData.append("csrfmiddlewaretoken",getCookie('csrftoken'));
httpRequest.onreadystatechange = alertContents;
httpRequest.open('POST', url, true);
//httpRequest.send();
httpRequest.send(formData);
...
最好不要这样将form元素传递给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");
导致矛盾的编码指令。 我只是完全删除了这一行,并且还避免在模板的form标记中指定“ enctype”,并将所有这些都由FormData()自动设置。 现在可以了!
再次感谢你的帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.