使用Dropzone结合FormValidation将多文件存入隐藏file字段同步提交方案
问题背景
项目中需要通过单次后端请求同时上传多个文件和其他表单字段值,设计的表单效果如下:
现有代码
表单代码
<form class="form-horizontal" name="addColorForm" id="addColorForm" enctype="multipart/form-data" method="POST"> //Colour Name和Code字段 //Dropzone文件上传插件 <input type="file" name="artworkFiles[]" style="visibility: hidden"/> </form>
脚本逻辑代码
<script> var validCode = function () { // 自定义校验逻辑 }; FormValidation.validators.validCode = validCode; FormValidation.formValidation( document.getElementById('addColorForm'), { fields: { colorName: { validators: { notEmpty: { message: '${message(code:"blank.error.message", default:"该字段不能为空")}' }, } }, }, plugins: { trigger: new FormValidation.plugins.Trigger(), // Bootstrap框架集成 bootstrap: new FormValidation.plugins.Bootstrap(), // 点击提交按钮时校验字段 submitButton: new FormValidation.plugins.SubmitButton(), // 所有字段校验通过后提交表单 // defaultSubmit: new FormValidation.plugins.DefaultSubmit(), } } ).on('core.form.valid', function () { saveColor(); }); function saveColor() { var url = "接口地址"; var form = $("#createArtworkForm"); var formData = new FormData(form[0]); $.ajax({ url: url, type: 'POST', enctype: 'multipart/form-data', data: formData, success: function (data) {}, cache: false, contentType: false, processData: false, error: function () { } }); } var artworkColorsFiles = $('#kt_dropzone').dropzone({ url: "https://www.google.com", // 上传接口地址 paramName: "media", // 文件传输的参数名 maxFiles: 1, maxFilesize: 40, // 单位MB addRemoveLinks: true, acceptedFiles: "image/*", autoProcessQueue: false, accept: function (file) { // 此处为将多个文件添加到上方声明的隐藏输入框的逻辑 let fileReader = new FileReader(); fileReader.readAsDataURL(file); fileReader.onloadend = function () { let content = fileReader.result; $('#artworkFiles').val(content); file.previewElement.classList.add("dz-success"); } file.previewElement.classList.add("dz-complete"); } }); </script>
问题描述
如何实现将最多3个选中的文件存入预先声明的、设置了visibility:hidden属性的<input type="file">字段中,最终实现所有表单数据同步提交?
解决方案
首先明确现有代码的两个核心问题:
- 出于浏览器安全限制,
<input type="file">的value属性是只读的,无法通过JS手动写入文件,原有通过FileReader转base64赋值的逻辑无效,提交后只会传输base64字符串而非真实文件,后端无法正常解析。 - 当前Dropzone配置的
maxFiles为1,仅支持上传1个文件,需要先调整为3。
具体修改步骤如下:
- 修改表单中的隐藏文件输入框,添加
multiple属性支持多文件,补全id属性方便识别:
<input type="file" name="artworkFiles[]" id="artworkFiles" style="visibility: hidden" multiple/>
- 修改Dropzone配置,调整文件上限,删除无效的FileReader逻辑:
var artworkColorsFiles = $('#kt_dropzone').dropzone({ url: "https://www.google.com", // 无需修改,不使用Dropzone自带提交逻辑 paramName: "media", maxFiles: 3, // 调整为最多支持3个文件 maxFilesize: 40, addRemoveLinks: true, acceptedFiles: "image/*", autoProcessQueue: false, accept: function (file, done) { file.previewElement.classList.add("dz-complete dz-success"); done(); } });
- 修改提交函数,手动将Dropzone选中的文件加入FormData中,和其他表单字段一起提交,注意修正原有表单id选择错误的问题:
function saveColor() { var url = "接口地址"; // 修正表单id,原表单id为addColorForm var form = $("#addColorForm"); var formData = new FormData(form[0]); // 手动添加Dropzone内选中的所有文件 var dropzoneFiles = Dropzone.forElement("#kt_dropzone").files; for(var i=0; i<dropzoneFiles.length; i++){ formData.append("artworkFiles[]", dropzoneFiles[i]); } $.ajax({ url: url, type: 'POST', enctype: 'multipart/form-data', data: formData, success: function (data) { // 提交成功逻辑 }, cache: false, contentType: false, processData: false, error: function () { // 错误处理逻辑 } }); }
修改完成后提交的FormData会同时包含普通表单字段和最多3个上传文件,后端按照常规multipart/form-data格式解析即可。
内容的提问来源于stack exchange,提问作者chaitanya gupta
相关产品推荐
相关产品推荐

