Laravel 8中无Form标签使用Dropzone.js多文件上传失败(419错误)及表单与文件一同提交方案咨询
Hey there! Let's break down and solve your problems step by step—you're dealing with a common CSRF token issue, plus figuring out how to tie your existing form fields to the Dropzone upload. Here's what to do:
1. Fix the 419 (Unknown Status) Error
This error happens because Laravel requires a CSRF token for all POST requests, and Dropzone doesn't include it by default. Here's how to add it:
First, make sure you have this meta tag in your HTML <head> (most Laravel projects already include it, but double-check):
<meta name="csrf-token" content="{{ csrf_token() }}">
Then update your Dropzone JS configuration to include the CSRF token in the request headers:
Dropzone.autoDiscover = false; $(document).ready(function(){ var myDropzone = new Dropzone("#multipleFileUpload", { url: '{{route("multiple.file.store")}}', acceptedFiles: ".jpg,.png,.jpeg,application/pdf", maxFiles: 10, addRemoveLinks: true, autoProcessQueue: false, // Add CSRF token to request headers headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, 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(); } }); } }); });
2. Submit Existing Form Fields Alongside Dropzone Files
To send your existing form's input fields with the Dropzone upload using the same submit button, use Dropzone's sending event to attach form data to the upload request.
Assume your existing form has an ID of existing-form (update this to match your actual form ID):
init: function () { var submitButton = document.querySelector("#submit"); var existingForm = document.querySelector("#existing-form"); myDropzone = this; // Attach form data when Dropzone sends a file this.on('sending', function(file, xhr, formData) { // Loop through all form fields and add them to the upload request Array.from(existingForm.elements).forEach(element => { if (element.name) { formData.append(element.name, element.value); } }); }); submitButton.addEventListener("click", function() { // Optional: Add form validation here before triggering upload // if ($('#existing-form').valid()) { myDropzone.processQueue(); // } }); this.on('complete', function(){ if (this.getQueuedFiles().length == 0 && this.getUploadingFiles().length == 0) { var _this = this; _this.removeAllFiles(); // Optional: Reset your existing form after upload completes // existingForm.reset(); } }); }
Now when you click the upload button, Dropzone will send both the files and all your form's input data to the controller. You can access the form fields in your controller using $request->input('your_field_name').
3. Polish Controller & Permissions
- Directory Permissions: Make sure the
public/imagesfolder has write access. On Linux servers, run these commands:
chmod -R 755 public/images chown -R www-data:www-data public/images
- Controller Improvements: Update your controller to handle validation and avoid duplicate filenames:
public function storeMultipleFile(Request $request) { // Validate the uploaded file $request->validate([ 'file' => 'required|file|mimes:jpg,png,jpeg,pdf|max:2048', // Adjust max size as needed ]); if ($request->hasFile('file')) { $image = $request->file('file'); // Use uniqid() to prevent filename collisions $imageName = time().'-'.uniqid().'.'.$image->extension(); $image->move(public_path('images'), $imageName); // If you need to save form data + file path to a database: // $formValue = $request->input('your_form_field'); // Document::create([ // 'file_path' => 'images/'.$imageName, // 'related_field' => $formValue, // ]); return response()->json(['success' => $imageName], 200); } return response()->json(['error' => 'No file uploaded'], 400); }
4. Optimize Route
Since this is an upload operation, change your route to use POST instead of any:
Route::post('/storeMultipleFile', [UploadsController::class, 'storeMultipleFile'])->name('multiple.file.store');
With these changes, your 419 error should disappear, files will upload correctly to the public/images directory, and your existing form fields will be submitted alongside the files.
内容的提问来源于stack exchange,提问作者Abhishek Poudel

