
📤 Téléchargement de fichiers par glisser-déposer avec Dropzone.js et PHP
Les utilisateurs s’attendent à pouvoir déposer des fichiers sur un site web en les faisant simplement glisser dans la fenêtre du navigateur. Le bouton «Choisir un fichier» et l’explorateur de fichiers sont déjà perçus comme des étapes superflues. Mais coder un glisser-déposer from scratch en JavaScript représente plusieurs centaines de lignes de code, entre les barres de progression, les aperçus et la gestion des erreurs. Heureusement, il existe une bibliothèque prête à l’emploi qui couvre tout cela de manière native.
Dropzone.js est une bibliothèque JavaScript open source dédiée au téléchargement de fichiers par glisser-déposer. Elle affiche des aperçus d’images, une barre de progression et ne nécessite pas jQuery. Elle fonctionne avec n’importe quel langage côté serveur: PHP, Node.js, Python. Dans ce guide, vous trouverez le cycle complet, de l’installation à la mise en production, en six étapes.
💡 Aperçu rapide:
- Ce qu’elle fait: la bibliothèque Dropzone.js transforme n’importe quel élément HTML en zone de dépôt de fichiers avec envoi AJAX vers le serveur.
- Comment l’installer: un lien CDN (unpkg ou jsDelivr) ou un paquet npm; les deux options sont traitées dans la première étape.
- Comment la prendre en charge côté serveur: un script PHP reçoit le fichier via
$_FILES, exactement comme un formulaire classique; la troisième étape inclut du code prêt à l’emploi. - Où l’appliquer: formulaires de contact avec pièces jointes, téléchargement d’avatars, import en masse d’images dans une galerie WordPress.
Étape 1: Installer Dropzone.js
La méthode la plus rapide consiste à inclure la bibliothèque via un CDN. Ajoutez cette balise dans le <head> de votre page:
1 <script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>
Le fichier CSS s’inclut séparément:
1 <link rel="stylesheet" href="https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" />
Si vous utilisez un bundler, installez-la via npm:
1 npm install dropzone
Et importez-la dans votre fichier JS:
1 import Dropzone from "dropzone";
Notez que la version 5.9 est la dernière version stable à date, début 2026. La version six est au stade bêta et n’est pas encore recommandée pour la production. Le dépôt du projet se trouve désormais à l’adresse github.com/dropzone/dropzone (auparavant enyo/dropzone).
Étape 2: Balisage HTML de base et initialisation
Créez un formulaire avec la classe dropzone. Dropzone le détectera automatiquement et le transformera en zone de dépôt:
1 <form action="/upload.php" 2 class="dropzone" 3 id="my-dropzone"></form>
C’est tout. Lorsqu’un utilisateur dépose un fichier dans ce formulaire, la bibliothèque l’envoie via une requête AJAX à l’URL indiquée dans l’attribut action. Côté serveur, le fichier arrivera dans $_FILES['file'], exactement comme avec une soumission classique via <input type="file">.

Si vous avez besoin d’une solution de repli pour les navigateurs sans JavaScript, ajoutez un champ standard dans le formulaire:
1 <form action="/upload.php" class="dropzone"> 2 <input name="file" type="file" multiple /> 3 </form>
Le bouton «Choose file» ne s’affichera que lorsque JavaScript est indisponible. Lorsque JS est activé, Dropzone le masquera et affichera sa propre zone de dépôt.
Step 3: Gestion des fichiers côté serveur
Un script PHP reçoit les téléchargements de la même manière qu’un formulaire classique. Voici la version minimale fonctionnelle:
1 <?php 2 if (!empty($_FILES)) { 3 $uploadDir = __DIR__ . '/uploads/'; 4 5 if (!is_dir($uploadDir)) { 6 mkdir($uploadDir, 0755, true); 7 } 8 9 $originalName = basename($_FILES['file']['name']); 10 $targetPath = $uploadDir . time() . '_' . $originalName; 11 12 if (move_uploaded_file($_FILES['file']['tmp_name'], $targetPath)) { 13 http_response_code(200); 14 echo json_encode(['status' => 'ok', 'file' => $targetPath]); 15 } else { 16 http_response_code(500); 17 echo json_encode(['status' => 'error', 'message' => 'Failed to save file']); 18 } 19 }
Voici ce qui se passe:
- Le script crée un dossier
uploads/s’il n’existe pas. time()est ajouté au nom de fichier d’origine, ce qui évite les conflits de noms.basename()supprime toute tentative d’attaque par traversée de chemin (tentative de sortir du dossier via../).- Dropzone attend un code HTTP 200 du serveur; dans le cas contraire, il considère que le téléchargement a échoué et affiche une erreur.
Pour la production, ajoutez une validation de l’extension et du type MIME:
1 $allowed = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'zip']; 2 $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION)); 3 4 if (!in_array($ext, $allowed)) { 5 http_response_code(400); 6 echo json_encode(['status' => 'error', 'message' => 'Invalid file type']); 7 exit; 8 }
Step 4: Limiter le nombre, la taille et le type de fichiers
Les trois paramètres Dropzone les plus couramment utilisés se configurent via un objet JavaScript:
1 Dropzone.options.myDropzone = { 2 maxFiles: 10, 3 maxFilesize: 5, // In megabytes 4 acceptedFiles: 'image/*,.pdf', 5 dictDefaultMessage: 'Drag files here or click to select' 6 };
Détail des options:
- maxFiles: nombre de fichiers que l’utilisateur peut télécharger en une fois. Par défaut, il n’y a pas de limite; dans l’exemple, pas plus de 10.
- maxFilesize: taille maximale d’un fichier en mégaoctets. Une valeur de 5 signifie 5 Mo. Dans les anciennes versions de la bibliothèque, la valeur par défaut était de 256 Mo; dans la version actuelle 5.x, elle est également de 256, il est donc préférable de spécifier explicitement votre propre limite.
- acceptedFiles: une chaîne de types MIME séparés par des virgules. Le motif
image/*autorise toutes les images,.pdfajoute le PDF à la liste. Consultez la liste complète des types MIME dans la documentation Dropzone. - dictDefaultMessage: le texte que l’utilisateur voit dans la zone de dépôt vide (en anglais dans cet exemple).
La clé myDropzone dans Dropzone.options.myDropzone est la version en camelCase de l’attribut HTML id="my-dropzone". Les tirets sont supprimés et chaque mot suivant prend une majuscule: my-dropzone → myDropzone, file-upload-area → fileUploadArea.
Les options resizeWidth et resizeHeight vous permettent de redimensionner les images côté client avant l’envoi. Cela économise la bande passante de l’utilisateur et réduit la charge du serveur, notamment lorsque les visiteurs téléchargent des photos prises au téléphone de 10 à 15 Mo chacune. Spécifiez les deux paramètres ensemble:
1 Dropzone.options.myDropzone = { 2 resizeWidth: 1200, 3 resizeHeight: 1200, 4 resizeQuality: 0.8, 5 resizeMethod: 'contain' 6 };
La méthode contain adapte l’image aux dimensions données sans la recadrer, tandis que crop la recadre aux dimensions exactes. Une qualité de 0.8 est pratiquement indiscernable de l’original mais réduit la taille du fichier de 4 à 7 fois. Important: le redimensionnement ne fonctionne qu’avec les fichiers image; les PDF et les archives sont transmis tels quels. Le navigateur effectue le redimensionnement via l’API Canvas, aucune bibliothèque supplémentaire n’est donc nécessaire.
Step 5: Soumission manuelle des fichiers
Par défaut, Dropzone envoie un fichier au serveur immédiatement après son ajout. Ce n’est pas toujours pratique: il peut être nécessaire de laisser l’utilisateur remplir des champs de formulaire à côté de la zone de dépôt, puis de tout soumettre avec un seul bouton.
Désactivez l’envoi automatique avec l’option autoProcessQueue: false et liez la soumission à un bouton externe:
1 Dropzone.options.myDropzone = { 2 autoProcessQueue: false, 3 maxFilesize: 5, 4 init: function () { 5 const myDropzone = this; 6 const submitBtn = document.querySelector('#btnUpload'); 7 8 submitBtn.addEventListener('click', function () { 9 if (myDropzone.getQueuedFiles().length === 0) { 10 alert('No files to upload'); 11 return; 12 } 13 myDropzone.processQueue(); 14 }); 15 16 this.on('success', function (file, response) { 17 console.log('File uploaded:', file.name); 18 }); 19 } 20 };
Le point clé ici est la méthode processQueue(). Elle déclenche l’envoi de tous les fichiers accumulés dans la file d’attente. L’événement success se déclenche pour chaque fichier individuellement, ce qui vous permet de mettre à jour l’interface ou de sauvegarder l’identifiant du fichier téléchargé dans un champ de formulaire caché.
Step 6: Envoyer des données supplémentaires avec le fichier
Il peut être nécessaire d’associer des paramètres de service à un téléchargement: identifiant utilisateur, statut du document, catégorie sélectionnée. Dropzone propose l’événement sending pour cela:
1 Dropzone.options.myDropzone = { 2 init: function () { 3 this.on('sending', function (file, xhr, formData) { 4 formData.append('status', 'draft'); 5 formData.append('user_id', currentUserId); 6 }); 7 8 this.on('success', function (file, responseText) { 9 console.log('Done:', responseText); 10 }); 11 } 12 };
L’événement sending est appelé juste avant l’envoi de la requête XMLHttpRequest. Le troisième argument formData est un objet FormData standard auquel vous pouvez ajouter n’importe quelle paire clé-valeur via append(). Côté serveur, ces paramètres sont lus depuis $_POST['status'] et $_POST['user_id'].
Scénario pratique: l’utilisateur sélectionne un album dans une liste déroulante à côté de la zone Dropzone, et l’identifiant de l’album est envoyé avec chaque fichier. Le serveur trie immédiatement les téléchargements dans les dossiers appropriés.
Sécurité: trois règles à ne pas ignorer
Avant de déployer Dropzone en production, vérifiez trois points.
Premièrement. Validez toujours le type et la taille du fichier côté serveur, même si vous avez déjà configuré acceptedFiles et maxFilesize en JS. Les restrictions côté client peuvent être contournées en une minute via la console du navigateur. Le filtrage côté serveur est la seule véritable protection.
Deuxièmement. Stockez les fichiers téléchargés en dehors de la racine du document ou dans un dossier où l’exécution des scripts est désactivée. Par exemple, cette structure:
1 /public_html ← document root ( index.php ) 2 /uploads ← folder with uploaded files (outside web access)
Dans ce cas, une URL directe vers le fichier ne fonctionnera pas; le navigateur ne sert le fichier qu’à travers un script PHP intermédiaire qui vérifie les droits d’accès.
Troisièmement. Générez des noms de fichier uniques côté serveur. Ne faites jamais confiance au nom envoyé par le client: il peut contenir ../, des octets nuls ou des caractères spéciaux. basename() + time() + une chaîne aléatoire constituent le minimum requis.
Quatrièmement. Vérifiez le contenu du fichier, pas seulement son extension. Un attaquant peut renommer shell.php en photo.jpg et contourner un filtre basé sur pathinfo(). Une approche fiable: déterminez le type MIME réel via finfo_file() (le module PHP Fileinfo intégré) et comparez-le à une liste blanche. Pour les images, vérifiez en plus que getimagesize() renvoie des dimensions valides; cela élimine les fichiers corrompus et les scripts déguisés. Sur les projets à fort trafic, envisagez de déléguer les téléversements à un microservice séparé, placé derrière un proxy inverse, qui reçoit le flux, le scanne avec un antivirus (par exemple ClamAV) et ne le transmet qu’ensuite à l’application principale.
La courte vidéo de démonstration ci-dessus montre l’ensemble du processus en action: le balisage HTML, le gestionnaire PHP et le résultat dans le navigateur, le tout en trois minutes.
⁉️🤔 Foire aux questions
Est-ce que Dropzone.js fonctionne sans jQuery?
Oui, la bibliothèque est totalement indépendante de jQuery. À partir de la version 5.x, toutes les dépendances ont été supprimées; consultez la section Installation sur dropzone.dev. Cela dit, il existe un wrapper jQuery séparé pour ceux qui préfèrent
$('.dropzone').dropzone(); il se trouve dans le même package npm, sousdist/min/dropzone-jquery.min.js.
Comment modifier le texte d’erreur lorsqu’un fichier est trop volumineux?
Utilisez l’option
dictFileTooBig. Exemple:dictFileTooBig: 'File is too big. Maximum size is {{maxFilesize}} MB'. Le placeholder{{maxFilesize}}insère automatiquement la valeur issue de votre configuration. La liste complète des clés de dictionnaire pour la localisation se trouve dans la documentation.
Peut-on envoyer les fichiers par morceaux pour les gros volumes?
Oui, Dropzone v5 prend en charge nativement l’envoi fragmenté via les options
chunking: true,chunkSize(en octets) etforceChunking. Le serveur doit être capable de reconstituer les morceaux: recevoir chaque fragment avec les en-têtesdzchunkindexetdztotalchunkcount, les sauvegarder temporairement, puis les fusionner après réception du dernier. Un exemple PHP prêt à l’emploi pour l’assemblage des fragments est disponible dans le dépôt Dropzone.
Comment supprimer l’aperçu d’un fichier après un envoi réussi?
Appelez
myDropzone.removeFile(file)dans le gestionnaire d’événementsuccess. Le fichier disparaîtra de l’interface mais restera sur le serveur. Si vous devez également le supprimer du serveur, ajoutez une requête AJAX dans le même gestionnaire avantremoveFile.
Dropzone est-il compatible avec WordPress?
Oui, la bibliothèque peut être incluse via
wp_enqueue_script()dans votre thème ou votre extension. Un scénario WordPress typique: remplacer l’uploader média standard sur une page d’administration personnalisée ou un formulaire en frontend. Il vous suffit de spécifier l’URL du gestionnaire approprié, généralementadmin_url('admin-ajax.php')avec une action AJAX enregistrée.
Dropzone.js est-il adapté à votre projet
Si vous avez besoin d’un envoi de fichiers par glisser-déposer «ici et maintenant», Dropzone.js résout la tâche plus rapidement que n’importe quel code sur mesure. Voici cinq raisons pour lesquelles la bibliothèque reste pertinente en 2026:
- Aucune dépendance. Ni jQuery, ni Bootstrap, ni React. Incluez un seul fichier JS et cela fonctionne.
- Support multi-navigateur. Compatible jusqu’à IE11 et se dégrade de manière élégante sans JavaScript.
- Visualisation prête à l’emploi. Aperçus d’image, barres de progression, icônes de succès/erreur immédiatement disponibles, sans aucun travail de mise en page CSS.
- Documentation. Un GitBook à jour et un dépôt GitHub actif (plus de 1 700 étoiles en 2026).
- Flexibilité. Du simple redimensionnement d’image avant envoi à l’envoi fragmenté de fichiers de plusieurs gigaoctets, tout est configurable.
Quand Dropzone n’est pas le meilleur choix: si vous utilisez déjà React ou Vue et souhaitez un composant natif sans manipulation externe du DOM. L’écosystème React propose react-dropzone, Vue a vue-dropzone. Mais pour le JavaScript vanilla, les projets jQuery et les sites WordPress, Dropzone.js est un outil éprouvé qui ne vous laissera pas tomber.
Exemple concret d’intégration. Un scénario WordPress typique: une page «Envoyer des documents» dans un portail client. L’utilisateur y glisse-dépose les scans d’un passeport, d’un contrat et des photos du bien. Dropzone est inclus via wp_enqueue_script() dans le fichier functions.php du thème, et le gestionnaire est une action AJAX personnalisée enregistrée via wp_ajax_nopriv_. Chaque fichier envoyé avec succès est ajouté à la médiathèque via wp_insert_attachment(), et son ID est sauvegardé dans les métadonnées utilisateur. L’ensemble du code frontend tient en 30 lignes, et la partie serveur en 50. À titre de comparaison, un glisser-déposer personnalisé offrant les mêmes capacités nécessiterait 400 à 600 lignes de JavaScript et 2 à 3 jours de développement.
Quant aux alternatives: Uppy (des créateurs de Transloadit) propose une architecture modulaire avec des plugins pour React, Svelte et les envois vers S3, mais exige davantage de dépendances et de configuration. Fine Uploader n’est plus maintenu depuis 2018; des forks existent mais sans garantie de sécurité. Dropzone.js l’emporte sur l’équilibre «fonctionnalités par unité de complexité»: un seul fichier, une configuration minimale et des résultats visibles cinq minutes après l’intégration.
Quelques capacités supplémentaires à connaître avant de commencer. Dropzone fournit un cycle d’événements complet: addedfile, thumbnail, uploadprogress, complete et queuecomplete. Ce dernier est particulièrement utile: il se déclenche lorsque tous les fichiers de la file d’attente ont été traités, ce qui vous permet d’afficher un message récapitulatif à l’utilisateur ou de le rediriger vers une autre page. En cas de défaillance réseau, une fonction de réessai est intégrée: en cas d’erreur d’envoi, Dropzone affiche un bouton «Réessayer» à côté de l’aperçu du fichier, et la nouvelle tentative passe par le même gestionnaire sans duplication de code. L’interface est entièrement localisable via les options dict: dictCancelUpload, dictRemoveFile, dictMaxFilesExceeded et environ deux douzaines d’autres clés. La prise en charge de la langue française se configure en cinq minutes en copiant un objet depuis la documentation. La bibliothèque pèse 28 Ko compressés (gzip), ce qui ajoute moins de 0,1 seconde au temps de chargement de la page sur une connexion mobile 4G. Toutes ces caractéristiques font de Dropzone.js le standard de fait pour les envois par glisser-déposer dans les projets sans framework: un million de téléchargements npm par semaine début 2026, et une utilisation dans les panneaux d’administration WordPress, Laravel et Symfony.



