Uploading large files efficiently is a common challenge in web applications. Dropzone.js provides an easy-to-use drag-and-drop file upload interface, and when combined with Laravel, it enables chunked file uploads to handle large files without hitting server limits. In this post, we will walk through setting up Dropzone.js with Laravel for chunked file uploads.
Prerequisites
Before you begin, ensure you have the following:
A Laravel project set up
jQuery and Dropzone.js installed
A configured Laravel route and controller for handling file uploads
Setting Up Dropzone.js
First, add the Dropzone.js script in your Blade template:
@push('dropzonejs')
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.2/min/dropzone.min.js"></script>
<script>
Dropzone.autoDiscover = false;
$(document).ready(function() {
var myDropzone = new Dropzone("#my-awesome-dropzone-anyfile", {
url: "{{ route('dropzone.uploader') }}",
acceptedFiles: "image/*",
method: "POST",
paramName: 'file',
maxFilesize: 2024,
addRemoveLinks: true,
autoProcessQueue: false,
parallelUploads: 100,
chunking: true,
chunkSize: 2 * 1024 * 1024,
forceChunking: true,
retryChunks: true,
retryChunksLimit: 3,
timeout: 0,
capture: 'camera',
init: function() {
console.log("Dropzone initialized");
this.on("success", function(file, response) {
console.log("Upload successful", response);
});
this.on("error", function(file, errorMessage, xhr) {
console.error("Upload Error:", errorMessage);
});
document.querySelector("#submit-all").addEventListener("click", () => {
console.log("Submitting all files...");
this.processQueue();
});
}
});
});
</script>
@endpushCreating Laravel File Upload Controller
Next, create a DropZoneController to handle the chunked file uploads.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Log;
use Pion\Laravel\ChunkUpload\Handler\HandlerFactory;
use Pion\Laravel\ChunkUpload\Receiver\FileReceiver;
class DropZoneController extends Controller
{
public function dropUploader(Request $request)
{
Log::info('Incoming Request for Large Uploader', [
'ip' => $request->ip(),
]);
if ($request->file('file')) {
$fileReceiver = new FileReceiver("file", $request, HandlerFactory::classFromRequest($request));
if (!$fileReceiver->isUploaded()) {
return response()->json(['error' => 'No file uploaded!'], 400);
}
$save = $fileReceiver->receive();
if ($save->isFinished()) {
return $this->saveFile($save->getFile());
}
return response()->json(["done" => $save->handler()->getPercentageDone(), 'status' => true]);
}
return response()->json(['error' => 'No file uploaded!'], 400);
}
protected function saveFile(UploadedFile $file)
{
$fileName = $this->createFilename($file);
$filePath = $file->storeAs('dropzone/uploads', $fileName, 'public');
Log::info("File saved at: " . $filePath);
return response()->json([
'path' => $filePath,
'name' => $fileName,
'mime_type' => $file->getMimeType()
]);
}
protected function createFilename(UploadedFile $file)
{
$extension = $file->getClientOriginalExtension();
$filename = str_replace("." . $extension, "", $file->getClientOriginalName());
return $filename . "_" . strtoupper(md5(time())) . "." . $extension;
}
}Configuring Routes
Define a route for handling the file upload request.
use App\Http\Controllers\DropZoneController;
Route::post('/dropzone/uploader', [DropZoneController::class, 'dropUploader'])->name('dropzone.uploader');By integrating Dropzone.js with Laravel, you can efficiently upload large files using chunked uploads. This approach prevents server overload and allows users to upload multiple files seamlessly. Happy coding!