
📤 Завантаження файлів перетягуванням з Dropzone.js і PHP
Користувачі очікують, що файли на сайт можна закинути, просто перетягнувши їх у вікно браузера. Кнопка «Виберіть файл» і провідник уже сприймаються як зайвий рух. Але писати drag-and-drop з нуля на JavaScript — це кілька сотень рядків коду, прогрес-бари, прев’ю та обробка помилок. На щастя, є готова бібліотека, яка закриває все це з коробки.
Dropzone.js — це open-source JavaScript-бібліотека для завантаження файлів перетягуванням. Показує прев’ю зображень, прогрес-бар і не потребує jQuery. Працює з будь-якою серверною мовою: PHP, Node.js, Python. У цьому посібнику, повний цикл від встановлення до продакшен-налаштування за шість кроків.
💡 Швидкий огляд:
- У чому суть: бібліотека Dropzone.js перетворює будь-який HTML-елемент на зону для перетягування файлів з AJAX-надсиланням на сервер.
- Як встановити: CDN-посилання (unpkg або jsDelivr) чи npm-пакет, обидва варіанти розглянуто в першому кроці.
- Як обробити на сервері: PHP-скрипт приймає файл через
$_FILES, як звичайну форму, третій крок із готовим кодом. - Де застосувати: контактні форми з вкладеннями, завантаження аватарів, масовий імпорт зображень у галерею WordPress.
Крок 1: Встановлення Dropzone.js
Найшвидший спосіб, підключити бібліотеку через CDN. Додайте цей тег у <head> сторінки:
1 <script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>
CSS-файл підключається окремо:
1 <link rel="stylesheet" href="https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" />
Якщо користуєтеся збирачем, встановлюйте через npm:
1 npm install dropzone
І імпортуйте у своєму JS-файлі:
1 import Dropzone from "dropzone";
Зверніть увагу: версія 5.9, остання стабільна на початок 2026 року. Шоста версія в статусі beta, для продакшену поки не рекомендована. Репозиторій проєкту тепер живе за адресою github.com/dropzone/dropzone (раніше був enyo/dropzone).
Крок 2: Базова HTML-розмітка та ініціалізація
Створіть форму з класом dropzone. Dropzone автоматично знайде її та перетворить на зону для перетягування:
1 <form action="/upload.php" 2 class="dropzone" 3 id="my-dropzone"></form>
Усе. Коли користувач перетягне файл у цю форму, бібліотека надішле його AJAX-запитом за адресою з атрибута action. На серверному боці файл потрапить у $_FILES['file'], так само як при звичайному надсиланні через <input type="file">.

Якщо потрібен fallback для браузерів без JavaScript, додайте всередину форми звичайне поле:
1 <form action="/upload.php" class="dropzone"> 2 <input name="file" type="file" multiple /> 3 </form>
Кнопка «Виберіть файл» буде показана лише тоді, коли JavaScript недоступний. Коли JS увімкнено, Dropzone приховає її та відобразить свою зону перетягування.
Крок 3: Обробка файлів на сервері
PHP-скрипт приймає завантаження так само, як звичайну форму. Мінімальний робочий варіант:
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' => 'Не удалось сохранить файл']); 18 } 19 }
Що тут відбувається:
- Скрипт створює папку
uploads/, якщо її немає. - До оригінального імені файлу додається
time(), це запобігає конфлікту імен. basename()обрізає можливі path-traversal-атаки (спроби вийти за межі папки через../).- Dropzone очікує від сервера HTTP 200, інакше вважає завантаження невдалим і показує помилку.
Для продакшену додайте ще перевірку розширення та 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' => 'Недопустимый тип файла']); 7 exit; 8 }
Крок 4: Обмеження кількості, розміру та типу файлів
Три найбільш затребувані налаштування Dropzone конфігуруються через JavaScript-конфіг:
1 Dropzone.options.myDropzone = { 2 maxFiles: 10, 3 maxFilesize: 5, // В мегабайтах 4 acceptedFiles: 'image/*,.pdf', 5 dictDefaultMessage: 'Перетащите файлы сюда или кликните для выбора' 6 };
Розбір опцій:
- maxFiles, скільки файлів користувач може завантажити за раз. Типово обмежень немає, у прикладі, не більше 10.
- maxFilesize, максимальний розмір одного файлу в мегабайтах. Значення 5 означає 5 МБ. У старих версіях бібліотеки типово стояло 256 МБ, в актуальній 5.x, теж 256, тому явно вкажіть свій ліміт.
- acceptedFiles, рядок із MIME-типами через кому. Шаблон
image/*дозволяє будь-які зображення,.pdfдодає PDF до списку. Повний перелік MIME-типів дивіться в документації Dropzone. - dictDefaultMessage, український текст, який користувач бачить у порожній зоні завантаження.
Ключ myDropzone у Dropzone.options.myDropzone — це camelCase-версія HTML-атрибута id="my-dropzone". Дефіси відкидаються, кожне наступне слово з великої літери: my-dropzone → myDropzone, file-upload-area → fileUploadArea.
Опція resizeWidth та resizeHeight дозволяє зменшувати зображення на клієнті до відправлення. Це економить трафік користувача та розвантажує сервер, особливо коли відвідувачі завантажують фотографії з телефону по 10-15 МБ кожна. Вказуйте обидва параметри одночасно:
1 Dropzone.options.myDropzone = { 2 resizeWidth: 1200, 3 resizeHeight: 1200, 4 resizeQuality: 0.8, 5 resizeMethod: 'contain' 6 };
Метод contain вписує зображення в задані межі без обрізання, crop обрізає до точних розмірів. Якість 0.8 на практиці не відрізнити від оригіналу, але вона зменшує розмір файлу в 4-7 разів. Важливо: ресайз працює лише з image-файлами, PDF та архіви пропускаються як є. Браузер виконує ресайз через Canvas API, додаткові бібліотеки не потрібні.
Крок 5: Ручне відправлення файлів
Типово Dropzone відправляє файл на сервер одразу після додавання. Це не завжди зручно: іноді потрібно дати користувачеві заповнити поля форми поруч із зоною завантаження, а відправити все однією кнопкою.
Вимикаємо автозавантаження прапорцем autoProcessQueue: false і вішаємо відправлення на зовнішню кнопку:
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('Нет файлов для загрузки'); 11 return; 12 } 13 myDropzone.processQueue(); 14 }); 15 16 this.on('success', function (file, response) { 17 console.log('Файл загружен:', file.name); 18 }); 19 } 20 };
Ключовий момент тут, метод processQueue(). Він запускає відправлення всіх файлів, накопичених у черзі. Подія success спрацьовує для кожного файлу окремо, можна оновити інтерфейс або записати ID завантаженого файлу в приховане поле форми.
Крок 6: Передавання додаткових даних разом із файлом
Іноді потрібно прикріпити до завантаження службові параметри: ID користувача, статус документа, вибрану категорію. У Dropzone для цього є подія sending:
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('Готово:', responseText); 10 }); 11 } 12 };
Подія sending викликається безпосередньо перед XMLHttpRequest-відправленням. Третій аргумент formData, стандартний об’єкт FormData, до якого можна додати будь-які пари «ключ-значення» через append(). На серверному боці ці параметри читаються з $_POST['status'] та $_POST['user_id'].
Практичний сценарій: користувач вибирає альбом у випадному списку поруч із Dropzone-зоною, і ID альбому надходить разом із кожним файлом, сервер одразу розкладає завантаження по потрібних папках.
Безпека: три правила, які не можна ігнорувати
Перед тим як віддавати Dropzone на продакшен, перевірте три моменти.
Перше. Завжди валідуйте тип і розмір файлу на серверному боці, навіть якщо вже налаштували acceptedFiles і maxFilesize у JS. Клієнтські обмеження обходяться за хвилину через консоль браузера. Серверний фільтр, єдиний реальний захист.
Друге. Зберігайте завантажені файли за межами document root або в папці з вимкненим виконанням скриптів. Наприклад, структура:
1 /public_html ← document root ( index.php ) 2 /uploads ← папка с загруженными файлами (вне web-доступа)
Тоді пряме посилання на файл не спрацює, браузер віддає файл лише через PHP-скрипт-посередник, який перевіряє права доступу.
Третє. Генеруйте унікальні імена файлів на сервері. Не довіряйте імені, яке надіслав клієнт: воно може містити ../, нульові байти або спецсимволи. basename() + time() + випадковий рядок, мінімальний рівень.
Четверте. Перевіряйте вміст файлу, а не лише розширення. Зловмисник може перейменувати shell.php на photo.jpg і обійти фільтр за pathinfo(). Надійний спосіб: визначити реальний MIME-тип через finfo_file() (вбудований PHP-модуль Fileinfo) і звірити з білим списком. Для зображень додатково перевірте, що getimagesize() повертає валідні розміри — це відсіє биті файли та замасковані скрипти. На високонавантажених проєктах варто винести завантаження в окремий мікросервіс за реверс-проксі, який приймає потік, сканує антивірусом (наприклад, ClamAV) і лише потім віддає основному застосунку.
Коротке демо-відео вище показує весь процес у дії: HTML-розмітка, PHP-обробник і результат у браузері за три хвилини.
⁉️🤔 Часті запитання
Dropzone.js працює без jQuery?
Так, бібліотека повністю незалежна від jQuery. Починаючи з версії 5.x, усі залежності видалено, див. розділ Installation на dropzone.dev. Водночас є окрема jQuery-обгортка для тих, хто звик до
$('.dropzone').dropzone(), вона лежить у тому самому npm-пакеті, шляхdist/min/dropzone-jquery.min.js.
Як змінити текст помилки, коли файл завеликий?
Використовуйте опцію
dictFileTooBig. Приклад:dictFileTooBig: 'Файл слишком большой. Максимальный размер, {{maxFilesize}} МБ'. Шаблон{{maxFilesize}}автоматично підставить значення з вашої конфігурації. Повний перелік dict-ключів для локалізації є в документації.
Чи можна завантажувати файли частинами для великих обсягів?
Так, у Dropzone v5 є вбудована підтримка чанкового завантаження через опції
chunking: true,chunkSize(у байтах) іforceChunking. Сервер при цьому повинен уміти збирати чанки: приймати кожен шматок із заголовкамиdzchunkindexіdztotalchunkcount, зберігати тимчасово та склеювати після отримання останнього. Для PHP готовий приклад збирання чанків є в репозиторії Dropzone.
Як видалити прев’ю файлу після успішного завантаження?
Викличте
myDropzone.removeFile(file)в обробнику подіїsuccess. Файл зникне з інтерфейсу, але на сервері залишиться. Якщо потрібно видалити і з сервера, додайте AJAX-запит у той самий обробник передremoveFile.
Dropzone сумісний із WordPress?
Так, бібліотеку можна підключити через
wp_enqueue_script()у темі або плагіні. Типовий сценарій для WordPress: заміна стандартного завантажувача медіафайлів на користувацькій адмін-сторінці або на фронтенд-формі. Потрібно лише вказати коректний URL обробника, зазвичайadmin_url('admin-ajax.php')із зареєстрованим AJAX-екшеном.
Чи варто брати Dropzone.js під ваш проєкт
Якщо вам потрібне завантаження файлів перетягуванням «тут і зараз», Dropzone.js закриває задачу швидше, ніж будь-який самописний код. П’ять причин, чому бібліотека залишається актуальною у 2026 році:
- Жодних залежностей. Ні jQuery, ні Bootstrap, ні React. Підключили один JS-файл, і працює.
- Кросбраузерність. Підтримує браузери аж до IE11, gracefully degradable без JavaScript.
- Готова візуалізація. Прев’ю зображень, прогрес-бари, іконки успіху/помилки, з коробки, без CSS-верстання.
- Документація. Актуальне GitBook та активний репозиторій на GitHub (1 700+ зірок на момент 2026 року).
- Гнучкість. Від простого ресайзу зображень перед надсиланням до чанкового завантаження гігабайтних файлів, усе налаштовується через конфіг.
Коли Dropzone не найкращий вибір: якщо ви вже використовуєте React/Vue і хочете нативний компонент без DOM-маніпуляцій ззовні. В екосистемі React є react-dropzone, у Vue, vue-dropzone. Але для чистого JavaScript, jQuery-проєктів і WordPress-сайтів Dropzone.js — це перевірений інструмент, який не підведе.
Практичний приклад інтеграції. Один із типових сценаріїв на WordPress-сайті: сторінка «Завантажити документи» в особистому кабінеті клієнта. Користувач перетягує скани паспорта, договору та фото об’єкта. Dropzone підключається через wp_enqueue_script() у functions.php теми, обробником слугує кастомний AJAX-екшен, зареєстрований через wp_ajax_nopriv_. Кожен успішно завантажений файл записується до медіабібліотеки через wp_insert_attachment(), а його ID зберігається в user meta. Весь фронтенд-код уміщається в 30 рядків, серверна частина, у 50. Для порівняння: самописний drag-and-drop із тими самими можливостями зайняв би 400-600 рядків JavaScript і 2-3 дні розробки.
Щодо альтернатив: Uppy (від творців Transloadit) пропонує модульну архітектуру з плагінами для React, Svelte та завантаження в S3, але потребує більше залежностей і налаштування. Fine Uploader більше не підтримується з 2018 року, форки живуть, але без гарантій безпеки. Dropzone.js виграє балансом «можливості на одиницю складності»: один файл, мінімум конфігурації, результат видно через п’ять хвилин після підключення.
Кілька додаткових можливостей, які варто знати перед стартом. Dropzone надає повний цикл подій: addedfile, thumbnail, uploadprogress, complete і queuecomplete. Остання особливо корисна: вона спрацьовує, коли всі файли з черги оброблені, і ви можете показати користувачеві підсумкове повідомлення або перенаправити на іншу сторінку. Для мережевих збоїв є вбудований retry: у разі помилки завантаження Dropzone показує кнопку «Повторити» поруч із прев’ю файлу, повторне надсилання йде через той самий обробник без дублювання коду. Інтерфейс повністю локалізується через словник dict-опцій: dictCancelUpload, dictRemoveFile, dictMaxFilesExceeded і ще два десятки ключів, підтримка української мови робиться за п’ять хвилин копіюванням об’єкта з документації. Бібліотека важить 28 КБ у стисненому вигляді (gzip), що додає менш ніж 0,1 секунди до завантаження сторінки на мобільному 4G. Усі ці властивості роблять Dropzone.js стандартом де-факто для drag-and-drop завантаження в проєктах без фреймворків: мільйон завантажень npm на тиждень за даними на початок 2026 року, використання в адмінках WordPress, Laravel і Symfony.



