Laravel 8集成Dropzone组件遇重复上传及文件夹上传无法拦截问题求助
我来帮你搞定这两个Dropzone的问题,咱们逐个拆解解决:
问题1:重复上传已完成的文件
问题原因
你当前的配置里,虽然uploadMultiple设为false,但当新文件添加时,之前已经上传完成的文件还留在Dropzone的上传队列中,导致每次有新文件加入时,整个队列都会被重新触发上传,所以会重复传之前的文件。
解决方案
我们需要在文件上传成功后,把它从上传队列里彻底移除,同时调整addedfiles的逻辑,确保每次只保留最新的文件,清理掉旧的文件和队列:
- 在
init方法里添加success事件监听,文件上传成功后将其从队列中移除 - 优化
addedfiles的逻辑,当文件数量超过1时,移除最旧的文件,同时清空队列里的旧任务
问题2:文件夹上传拦截失效
问题原因
maxFiles:1只能限制最终显示的文件数量,但当你拖放整个文件夹时,Dropzone会先把文件夹里的所有文件都加入临时队列,之后才会触发maxFiles的限制,这就导致你看到的拦截效果滞后,看起来像是没生效。
解决方案
我们需要在文件被添加进来之前就拦截文件夹,同时优化拖放事件,直接阻止文件夹的拖放操作:
- 添加
accept函数,判断如果是文件夹就拒绝添加 - 监听
drop事件,检查拖放的是否是文件夹,如果是就阻止默认行为并提示用户
修改后的完整配置代码
var refType = $('#reference-type'); electronic = $('.electronic'), image = $('.image'), description = $('.description'), url = "{{ route('user.bank.files') }}", submitRef = $('#submit-ref'); Dropzone.autoDiscover=false; var imageDropzone; var config = { url: url, headers: {'X-CSRF-TOKEN':'{{ csrf_token() }}'}, uploadMultiple: false, maxFiles: 1, maxFilesize: 1, paramName: 'reference_image', addRemoveLinks: true, acceptedFiles: 'image/jpeg, image/png , image/jpg, image/svg', init: function() { imageDropzone = this; // 修复重复上传:上传成功后从队列移除文件,避免重复触发上传 this.on('success', function(file) { // 先移除队列中的该文件,避免后续重复上传 this.removeFile(file); // 重新添加预览(因为removeFile会删掉预览,我们需要保留已上传的预览) this.files.push(file); file.status = Dropzone.SUCCESS; this.updateTotalUploadProgress(100, 1); }); // 拦截文件夹拖放:直接阻止文件夹的拖放行为 this.on('drop', function(event) { var items = event.dataTransfer.items; for (var i = 0; i < items.length; i++) { if (items[i].kind === 'file' && items[i].webkitGetAsEntry().isDirectory) { event.preventDefault(); NioApp.Toast("{{ __('文件夹上传已被禁止,请单独选择图片文件') }}", 'error'); break; } } }); }, removedfile: function (file) { if (file.accepted) { data = { action: 'delete', tnx_id: "{{ the_tnx(data_get($order, 'tnx')) }}" }; NioApp.Form.toPost(url, data); } var _ref; return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0; }, sending: function(data, xhr, formData) { formData.append('action', 'store'); formData.append('tnx_id', "{{ the_tnx(data_get($order, 'tnx')) }}"); }, addedfiles: function (files) { // 优化文件数量限制:只保留最新的1个文件 if (this.files.length > this.options.maxFiles) { var oldFile = this.files[0]; this.removeFile(oldFile); NioApp.Toast("{{ __('You can upload only one :file.', ['file' => 'image']) }}", 'warning'); } }, accept: function(file, done) { // 拦截文件夹:判断文件是否为文件夹类型 if (file.type === '' || file.type === 'application/x-directory') { done("{{ __('禁止上传文件夹,请选择图片文件') }}"); return; } done(); }, error: function(file, errorMessage) { $.each(imageDropzone.files, function(i, file) { file.status = Dropzone.QUEUED }); } }; $("#reference-image").dropzone({...config});
关键修改点说明
- 重复上传修复:
- 在
init中添加success事件,文件上传成功后先从队列移除,再重新加入并标记为成功状态,确保队列里没有已完成的任务,新文件添加时只会上传当前文件
- 在
- 文件夹上传拦截修复:
- 添加
accept函数,判断文件类型是否为文件夹(部分浏览器会标记为application/x-directory),直接拒绝添加 - 监听
drop事件,通过dataTransfer.items检查是否是文件夹,阻止默认拖放行为并提示用户
- 添加
- 文件数量限制优化:
- 修改
addedfiles逻辑,当文件数超过限制时,移除最旧的文件而不是第二个,逻辑更严谨
- 修改
内容的提问来源于stack exchange,提问作者Tariq Imtinan
相关产品推荐
相关产品推荐

