我有一个带有表单元素的django模板,其中包含一些输入文本编辑和一个提交按钮以及一个带有DropzoneJS的用户头像上传。
问题是我无法将DropzonJs
放入我的表单中的div中,因为它会引发csrf_token error
。当我在csrf_token
中div
dropzoneJS;
时,csrf_token
没有任何变化。我还发现HTML
仅适用于<form role="form" method="POST">
{% csrf_token %}
<h5>Edit Profile Details</h5>
<div class="content">
<h1>{{ username }}</h1>
<!-- My other fields here -->
<div class="m-b-sm">
<img alt="image" class="img-circle" src="{% static 'img/profile.jpg' %}" />
</div>
<!-- Here is the div that contains DropzoneJS -->
<div class="dropzone dropzone-previews" id="my-awesome-dropzone" action="">
{% csrf_token %}
</div>
</div>
<!-- ... -->
表单元素。
这是我的模板:
{% csrf_token %}
我的想法是,如果我在表单中添加{% csrf_token %}
,则无需在其内部元素中添加其他<form class="dropzone" action="{% url "test_avatar" %}" method="post" enctype="multipart/form-data" id="my-awesome-dropzone">
{% csrf_token %}
</form>
。
DropzoneJS的工作方式如下:
HTML
但由于嵌套$i =& get_instance();
表单元素的错误,我无法在表单中使用此表单。
我该怎么办?
答案 0 :(得分:3)
您应该以编程方式创建dropzone实例,并将csrf_token附加到formData对象。
首先,将令牌存储在html中的某个javascript变量中:
(我自己使用PHP / Laravel,所以我不确定这是否打印出令牌,但你明白了。)
<script>
token = {% csrf_token %};
</script>
然后在您的javascript文件(或内联)中创建dropzone实例:
var myDropzone = new Dropzone(".dropzone", {
url: '/file/upload', // your test_avatar route here
sending: function(file, xhr, formData) {
formData.append("csrf_token", token);
// the first parameter should be the fieldname that django is looking for
// the second parameter being the token from the variable set in your html
},
});
答案 1 :(得分:3)
丹尼斯的答案是一个很好的线索,但你需要更多的细节来实现目标。您将在非表单HTML元素上以编程方式创建 ,然后将CSRF标记添加到它在文件上载期间发送的数据中。
(顺便说一下,如果你在网站的其他地方使用AJAX,你可能会使用框架(jQuery)钩子将CSRF令牌附加到所有AJAX帖子---但Dropzone没有使用你的框架,这就是为什么它没有得不到CSRF令牌。)
我们走了。使用常规div(或其他非形式HTML元素)作为Dropzone:
<div id="my_dropzone"></div>
在JavaScript中定义一个可以帮助您获取CSRF令牌的函数:
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
制作你的Dropzone。使用params字段在文件上载期间发送CSRF令牌:
var my_dropzone = new Dropzone('#my_dropzone', {
'url': '/avatar-upload', # url for view that handles upload
'params': {'csrfmiddlewaretoken': getCookie('csrftoken')}
})