当我将 dropzone 添加到 Django 中的现有表单时,CSRF 令牌问题

Posted

技术标签:

【中文标题】当我将 dropzone 添加到 Django 中的现有表单时,CSRF 令牌问题【英文标题】:CSRF Token problem when I add dropzone to an existing form in Django 【发布时间】:2021-12-01 15:12:50 【问题描述】:

我正在使用 Django 表单使用 dropzone 上传图像。但我不想将 dropzone 添加到整个表单中,只是添加到它的 div 中。这是模板:

% extends 'base.html' %
% load static %
% load i18n %
% block content %
<h6>UPLOAD MULTIPLE IMAGES NOW</h6>
<br>
<div class="formdiv" style="width:100%">
<form enctype="multipart/form-data" action="upload/" methd="POST">
    % csrf_token %
    <fieldset>
        <label for="yourname">Yourname
            <input type="text" value="name" />
        </label>
        <div class="dropzone dz" id="my-dropzone">
            <div class="dz-message" data-dz-message><span>% trans "Drop here or click to upload" %</span></div>
            <div class="fallback">
                <input name="file" type="file" multiple />
            </div>
        </div>
    </fieldset>
</form>
</div>
% endblock %

问题是,当我尝试上传任何图片时,我会收到一条包含以下文本的 Forbidden 错误消息:

CSRF token missing or incorrect.

请注意,如果我从 div 中删除 class="dropzone dz" id="my-dropzone" 并将其放在 &lt;form&gt; 标记中,一切都会正常工作。当我在 div 中移动 dropzone 时,问题就开始了,因为我不希望它应用于整个表单。

这是我的 dropzone 配置代码:

Dropzone.autoDiscover=false;
const myDropzone = new Dropzone('#my-dropzone',
    url:'upload/',
    maxFiles:15,
    maxFilesize:5, // 5 mb max
    //parallelUploads:2,
    // if image is horizontal, then resize it if it's more than resizeWidth
    resizeWidth:1024,
    // if the image is vertical, then resize if it's more than resizeHeight
    resizeHeight:1024,
    // also they can be mime such as image/png
    acceptedFiles: ".png,.jpg,.gif,.bmp,.jpeg,.webp",
    // default is false and it allows to delete uploaded files
    addRemoveLinks: true,
    // this is the element where the remove button or text will be located
    dictRemoveFile: "<div><span class='fa fa-trash text-danger' style='font-size: 1.5em;cursor:pointer'></span></div>",
 
    /* the following solution failed
    headers: 
        'X-CSRFToken': $('meta[name="token"]').attr('content')
     */
);

我必须做些什么来解决这个问题?

【问题讨论】:

如果您登录$('meta[name="token"]').attr('content'),它看起来是否正确? 你的意思是在浏览器的控制台中创建一个console.log吗?我试过这种方式,我得到未定义。 我做到了。这意味着您实际上并没有发送令牌。 因此,如果我将 class="dropzone dz" id="my-dropzone" 放入表单标签中,我会发送令牌,如果我将其放入 div 中,则不会发送令牌。最大的问题是为什么? 【参考方案1】:

看着django docs 我看到它被称为 X-CSRFToken 不是 X-CSRF-TOKEN。尝试修复它并取消注释您的标头代码。

我在the docs 中看到的获取令牌的代码是 document.querySelector('[name=csrfmiddlewaretoken]').value 尝试用它替换你的。请确保您的页面中某处有% csrf_token %

【讨论】:

我完全按照您的建议进行了尝试: headers: 'X-CSRFToken': $('meta[name="token"]').attr('content') 但我仍然有同样的问题。也许是另一个拼写错误的关键字? @Danilo 编辑帖子以包含获取令牌的正确方法 哦,现在很好用。所以正确的行是'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value;

以上是关于当我将 dropzone 添加到 Django 中的现有表单时,CSRF 令牌问题的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 表单中包含 Dropzone 表单时无法进行完整的 POST

如果刷新或选项卡已关闭,则 Dropzone 删除文件

如何使用 ReactJs 中的 dropzone 将文件及其描述添加到状态?

尝试使用 django 和 dropzone/

多对多字段django以两种方式添加关系

当我将 Django 应用程序部署到 Heroku 时,为啥 collectstatic 不会自动运行?