Laravel中Dropzone.js多图更新时请求无文件值的解决问询
Dropzone.js多图更新时无法获取文件请求值的解决方法
我使用Dropzone.js实现多图拖拽上传功能,新增(store)图片时可正常上传,但更新多图时,执行dd(request()->all())无法获取到多图文件值,仅能获取表单字段值。我已尝试设置paramName为'file',但仍无法获取文件请求值。请问如何实现多图更新并获取请求中的文件值存入数据表?
提供的edit.blade.php代码
JavaScript部分
let companyId = @json($companies); Dropzone.autoDiscover = false; document.addEventListener('DOMContentLoaded', function(e) { $(document).ready(function() { (function() { var myDropzone = new Dropzone("#multipleFileUpload", { url: '/admin/company/update/' + companyId, method: 'POST', paramName: 'file', headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, acceptedFiles: ".jpg,.png,.jpeg", maxFiles: 999, maxFilesize: 2, addRemoveLinks: true, uploadMultiple: false, autoProcessQueue: false, parallelUploads: 999, dictCancelUpload: "Cancel", dictDefaultMessage: "Please drag & drop images here", timeout: 5000, init: function() { dzClosure = this; // Makes sure that 'this' is understood inside the functions below. // for Dropzone to process the queue (instead of default form behavior): document.getElementById("submitButton").addEventListener( "click", function(e) { // Make sure that the form isn't actually being sent. e.preventDefault(); e.stopPropagation(); dzClosure.processQueue(); }); // send all the form data along with the files: this.on("sendingmultiple", function(data, xhr, formData) { formData.append("name", jQuery("#name").val()); formData.append("email", jQuery("#email").val()); formData.append("dropzone", jQuery("#multipleFileUpload").val()); formData.append("file", document.getElementById('multipleFileUpload')); formData.append("logo", document.getElementById('companyLogo').files[0]); formData.append("phone_number", jQuery("#phoneNumber").val()); formData.append("fax_number", jQuery("#faxNumber").val()); formData.append("address1", jQuery("#address1").val()); formData.append("address2", jQuery("#address2").val()); formData.append("city", jQuery("#city").val()); formData.append("postcode", jQuery("#postcode").val()); formData.append("state", jQuery("#state").val()); formData.append("country", jQuery("#country").val()); formData.append("longitude", jQuery("#longitude").val()); formData.append("latitude", jQuery("#latitude").val()); }); }, success: function(file, response) { Swal.fire({ title: 'Success!', text: 'Image added successfully', confirmButtonText: 'Ok', }).then(function() { window.location.href = "{{ route('admin.company.index') }}"; }); }, error: function() { return false; }, init: function() { var submitButton = document.querySelector("#submit"); myDropzone = this; submitButton.addEventListener("click", function() { myDropzone.processQueue(); }); this.on('complete', function() { if (this.getQueuedFiles().length == 0 && this.getUploadingFiles().length == 0) { var _this = this; _this.removeAllFiles(); } }); } }); })(); }); });
HTML部分
<div class="col-12 form-group"> <div class="card"> <div class="card-header">Image Upload</div> <div class="card-body"> <div class="dropzone" id="multipleFileUpload" name="dropzone"> @foreach ($companies->images as $image) <div class="img-wrap"> <a href="#" onclick="deleteImage({{ $image->id }})" class="close btn-delete btn-image-delete" id="btn-delete" data-image-id={{ $image->id }}>×</a> <img class="image-dropzone" src="{{ asset($image->location) }}" width="100px" height="100px" alt="image" style="background-position: center background-attachment: fixed;" data-image-id="{{ $image->id }}" name="images"> </div> @endforeach <input type="hidden" name="upload_image" value="{{ $image->id }}"> </div> </div> </div> </div>
问题分析与解决方案
核心问题
- 重复定义
init方法:代码中写了两个init,后一个会覆盖前一个,导致sendingmultiple事件未被绑定,同时提交按钮的逻辑冲突。 - 错误手动添加
file字段:在sendingmultiple里手动追加formData.append("file", document.getElementById('multipleFileUpload'));,传入的是DOM元素而非实际上传的文件,干扰了Dropzone的自动文件处理。 uploadMultiple配置关闭:当前设置uploadMultiple: false,Dropzone会逐个上传文件,而非批量提交,导致后端无法一次性获取所有文件。
修复步骤
- 合并
init方法:将两个init里的逻辑整合到一个方法中,避免覆盖。 - 移除手动添加的
file字段:Dropzone会自动处理选中的文件,无需手动追加。 - 开启多文件上传模式:设置
uploadMultiple: true,让Dropzone批量提交文件数组。 - 添加删除图片的标记逻辑:给已有图片的删除按钮绑定事件,将待删除的图片ID存入隐藏字段,后端更新时处理删除操作。
- 后端正确接收文件:后端通过
request()->file('file')获取文件数组,循环处理每个文件的上传。
修改后的关键代码示例
JavaScript部分(合并后的init)
init: function() { const dzClosure = this; // 绑定提交按钮事件 const submitButton = document.querySelector("#submit"); submitButton.addEventListener("click", function(e) { e.preventDefault(); e.stopPropagation(); dzClosure.processQueue(); }); // 绑定sendingmultiple事件,追加表单数据 this.on("sendingmultiple", function(data, xhr, formData) { // 追加表单字段 formData.append("name", jQuery("#name").val()); formData.append("email", jQuery("#email").val()); formData.append("logo", document.getElementById('companyLogo').files[0]); formData.append("phone_number", jQuery("#phoneNumber").val()); // ... 其他表单字段省略 // 追加待删除的图片ID formData.append("delete_images", JSON.stringify(window.deleteImageIds || [])); }); // 上传完成后清空队列 this.on('complete', function() { if (this.getQueuedFiles().length === 0 && this.getUploadingFiles().length === 0) { this.removeAllFiles(); } }); }, uploadMultiple: true, // 开启多文件上传
删除图片的JS逻辑(新增)
// 全局存储待删除的图片ID window.deleteImageIds = []; function deleteImage(imageId) { // 确认删除 if (confirm("确定要删除这张图片吗?")) { // 将ID加入待删除数组 window.deleteImageIds.push(imageId); // 移除页面上的图片元素 document.querySelector(`[data-image-id="${imageId}"]`).closest('.img-wrap').remove(); } }
后端处理示例(Laravel)
public function update(Request $request, $id) { $company = Company::findOrFail($id); // 处理表单字段更新 $company->update($request->only(['name', 'email', 'phone_number', ...])); // 处理新上传的图片 if ($request->hasFile('file')) { foreach ($request->file('file') as $file) { // 上传文件到存储 $path = $file->store('company_images', 'public'); // 保存到关联表 $company->images()->create(['location' => $path]); } } // 处理待删除的图片 if ($request->has('delete_images')) { $deleteIds = json_decode($request->delete_images); Image::whereIn('id', $deleteIds)->where('company_id', $company->id)->delete(); } return redirect()->route('admin.company.index')->with('success', '更新成功'); }
内容的提问来源于stack exchange,提问作者Md Amirul
相关产品推荐
相关产品推荐

