Skip to content

Alt om WordPress, webutvikling — og mer til

📤 Filopplasting med dra og slipp ved hjelp av Dropzone.js og PHP

📤 Filopplasting med dra og slipp ved hjelp av Dropzone.js og PHP

Brukere forventer å kunne laste opp filer til et nettsted ved å bare dra dem inn i nettleservinduet. «Velg fil»-knappen og filutforskeren oppleves allerede som unødvendige steg. Men å skrive dra-og-slipp fra bunnen av i JavaScript betyr flere hundre linjer med kode, fremdriftsindikatorer, forhåndsvisninger og feilhåndtering. Heldigvis finnes det et ferdig bibliotek som dekker alt dette ut av boksen.

Dropzone.js er et åpen kildekode JavaScript-bibliotek for dra-og-slipp filopplasting. Det viser forhåndsvisninger av bilder, en fremdriftsindikator og krever ikke jQuery. Det fungerer med et hvilket som helst serversidespråk: PHP, Node.js, Python. I denne veiledningen finner du hele syklusen fra installasjon til produksjonsoppsett i seks trinn.

💡 Rask oversikt:

  • Hva det gjør: Dropzone.js-biblioteket gjør et hvilket som helst HTML-element om til en slippsone for filer med AJAX-innsending til serveren.
  • Slik installerer du: en CDN-lenke (unpkg eller jsDelivr) eller en npm-pakke; begge alternativene dekkes i første trinn.
  • Slik håndterer du på serveren: et PHP-skript mottar filen via $_FILES, akkurat som et vanlig skjema; det tredje trinnet inneholder kode du kan bruke direkte.
  • Hvor det kan brukes: kontaktskjemaer med vedlegg, avatarlasting, bulkimport av bilder til et WordPress-galleri.

Trinn 1: Installere Dropzone.js

Den raskeste måten er å inkludere biblioteket via CDN. Legg til denne taggen i sidens <head>:

1<script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>

CSS-filen inkluderes separat:

1<link rel="stylesheet" href="https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" />

Hvis du bruker en bundler, installer via npm:

1npm install dropzone

Og importer det i JS-filen din:

1import Dropzone from "dropzone";

Merk at versjon 5.9 er den nyeste stabile utgivelsen per tidlig 2026. Versjon seks er i betastatus og anbefales ennå ikke for produksjon. Prosjektets kodelager ligger nå på github.com/dropzone/dropzone (tidligere enyo/dropzone).

Trinn 2: Grunnleggende HTML-markering og initialisering

Opprett et skjema med klassen dropzone. Dropzone vil automatisk finne det og gjøre det om til en slippsone:

1<form action="/upload.php"
2 class="dropzone"
3 id="my-dropzone"></form>

Det er alt. Når en bruker drar en fil inn i dette skjemaet, vil biblioteket sende den via en AJAX-forespørsel til URL-en i action-attributtet. På serversiden vil filen ankomme i $_FILES['file'], nøyaktig som ved en vanlig innsending gjennom <input type="file">.

Utvikler som skriver kode for filopplastinger

Trenger du en fallback for nettlesere uten JavaScript, legger du til et vanlig felt i skjemaet:

1<form action="/upload.php" class="dropzone">
2 <input name="file" type="file" multiple />
3</form>

«Velg fil»-knappen vises bare når JavaScript ikke er tilgjengelig. Med JS aktivert vil Dropzone skjule den og vise sin egen slippsone.

Trinn 3: Håndtering av filer på serveren

Et PHP-skript mottar opplastinger på samme måte som et vanlig skjema. Her er den minimale fungerende versjonen:

1<?php
2if (!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}

Hva som skjer her:

  • Skriptet oppretter en uploads/-mappe hvis den ikke finnes.
  • time() legges til det opprinnelige filnavnet, noe som forhindrer navnekonflikter.
  • basename() fjerner eventuelle path-traversal-angrep (forsøk på å unnslippe mappen via ../).
  • Dropzone forventer HTTP 200 fra serveren; ellers anser den opplastingen som mislykket og viser en feilmelding.

For produksjon bør du legge til validering av filtype og MIME-type:

1$allowed = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'zip'];
2$ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
3
4if (!in_array($ext, $allowed)) {
5 http_response_code(400);
6 echo json_encode(['status' => 'error', 'message' => 'Invalid file type']);
7 exit;
8}

Trinn 4: Begrensning av antall, størrelse og type filer

De tre mest brukte Dropzone-innstillingene konfigureres via et JavaScript-oppsett:

1Dropzone.options.myDropzone = {
2 maxFiles: 10,
3 maxFilesize: 5, // In megabytes
4 acceptedFiles: 'image/*,.pdf',
5 dictDefaultMessage: 'Drag files here or click to select'
6};

Gjennomgang av alternativene:

  • maxFiles: hvor mange filer brukeren kan laste opp samtidig. Som standard er det ingen grense; i eksemplet er det maksimalt 10.
  • maxFilesize: maksimal størrelse på én enkelt fil i megabyte. En verdi på 5 betyr 5 MB. I eldre bibliotekversjoner var standarden 256 MB; i gjeldende 5.x er den også 256, så angi eksplisitt din egen grense.
  • acceptedFiles: en kommaseparert streng med MIME-typer. Mønsteret image/* tillater alle bilder, .pdf legger PDF til i listen. Se hele listen over MIME-typer i Dropzone-dokumentasjonen.
  • dictDefaultMessage: teksten brukeren ser i den tomme opplastingssonen (engelsk i dette eksemplet).

Nøkkelen myDropzone i Dropzone.options.myDropzone er camelCase-versjonen av HTML-attributtet id="my-dropzone". Bindestreker fjernes og hvert påfølgende ord får stor forbokstav: my-dropzonemyDropzone, file-upload-areafileUploadArea.

Alternativene resizeWidth og resizeHeight lar deg forminske bilder på klientsiden før de sendes. Dette sparer brukerens båndbredde og reduserer serverbelastningen, spesielt når besøkende laster opp mobilbilder på 10-15 MB hver. Spesifiser begge parameterne sammen:

1Dropzone.options.myDropzone = {
2 resizeWidth: 1200,
3 resizeHeight: 1200,
4 resizeQuality: 0.8,
5 resizeMethod: 'contain'
6};

Metoden contain tilpasser bildet innenfor de gitte grensene uten å beskjære, mens crop beskjærer til nøyaktige dimensjoner. En kvalitet på 0.8 er praktisk talt umulig å skille fra originalen, men reduserer filstørrelsen med 4-7 ganger. Viktig: endring av størrelse fungerer bare med bildefiler; PDF-er og arkiver sendes gjennom som de er. Nettleseren utfører størrelsesendringen via Canvas API-et, så ingen ekstra biblioteker er nødvendige.

Trinn 5: Manuell innsending av filer

Som standard sender Dropzone en fil til serveren umiddelbart etter at den er lagt til. Dette er ikke alltid praktisk: noen ganger må du la brukeren fylle ut skjemafelter ved siden av opplastingssonen og sende inn alt med én enkelt knapp.

Deaktiver automatisk opplasting med flagget autoProcessQueue: false og knytt innsendingen til en ekstern knapp:

1Dropzone.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};

Nøkkelpunktet her er metoden processQueue(). Den utløser innsendingen av alle filer som er samlet i køen. Hendelsen success utløses for hver enkelt fil, noe som lar deg oppdatere grensesnittet eller lagre den opplastede filens ID i et skjult skjemafelt.

Trinn 6: Sende tilleggsdata sammen med filen

Noen ganger må du legge ved tjenesteparametere til en opplasting: bruker-ID, dokumentstatus, valgt kategori. Dropzone har hendelsen sending for dette:

1Dropzone.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};

Hendelsen sending kalles rett før XMLHttpRequest sendes. Det tredje argumentet formData er et standard FormData-objekt som du kan legge til nøkkel-verdi-par i via append(). På serversiden leses disse parameterne fra $_POST['status'] og $_POST['user_id'].

Praktisk scenario: brukeren velger et album fra en nedtrekksmeny ved siden av Dropzone-området, og album-ID-en sendes sammen med hver fil. Serveren sorterer umiddelbart opplastingene i de riktige mappene.

Sikkerhet: tre regler du ikke kan ignorere

Før du tar Dropzone i bruk i produksjon, må du sjekke tre ting.

For det første. Valider alltid filtype og størrelse på serversiden, selv om du allerede har konfigurert acceptedFiles og maxFilesize i JS. Begrensninger på klientsiden kan omgås på et minutt via nettleserkonsollen. Filtrering på serversiden er den eneste reelle beskyttelsen.

For det andre. Lagre opplastede filer utenfor dokumentroten eller i en mappe med skriptkjøring deaktivert. For eksempel denne strukturen:

1/public_html ← document root ( index.php )
2/uploads ← folder with uploaded files (outside web access)

Da vil en direkte URL til filen ikke fungere; nettleseren serverer filen kun gjennom et PHP-mellomledd som sjekker tilgangsrettigheter.

For det tredje. Generer unike filnavn på serveren. Ikke stol på navnet klienten sender: det kan inneholde ../, nullbytes eller spesialtegn. basename() + time() + en tilfeldig streng er minimumsnivået.

For det fjerde. Sjekk filinnholdet, ikke bare filtypen. En angriper kan omdøpe shell.php til photo.jpg og omgå et pathinfo()-filter. En pålitelig tilnærming: fastslå den faktiske MIME-typen via finfo_file() (den innebygde PHP Fileinfo-modulen) og sammenlign med en hvitliste. For bilder, verifiser i tillegg at getimagesize() returnerer gyldige dimensjoner; dette filtrerer bort ødelagte filer og forkledde skript. På prosjekter med høy trafikk bør du vurdere å avlaste opplastinger til en separat mikrotjeneste bak en omvendt proxy som mottar strømmen, skanner med antivirus (for eksempel ClamAV), og først deretter sender den videre til hovedapplikasjonen.

Den korte demovideoen over viser hele prosessen i aksjon: HTML-markup, PHP-håndterer og resultatet i nettleseren på tre minutter.

⁉️🤔 Ofte stilte spørsmål

Fungerer Dropzone.js uten jQuery?

Ja, biblioteket er helt uavhengig av jQuery. Fra og med versjon 5.x er alle avhengigheter fjernet; se installasjonsdelen på dropzone.dev. Når det er sagt, finnes det en separat jQuery-wrapper for dem som foretrekker $('.dropzone').dropzone(); den ligger i samme npm-pakke under dist/min/dropzone-jquery.min.js.

Hvordan endrer jeg feilmeldingen når en fil er for stor?

Bruk innstillingen dictFileTooBig. Eksempel: dictFileTooBig: 'File is too big. Maximum size is {{maxFilesize}} MB'. Plassholderen {{maxFilesize}} setter automatisk inn verdien fra konfigurasjonen din. Den fullstendige listen over dict-nøkler for lokalisering finnes i dokumentasjonen.

Kan filer lastes opp i biter for store datamengder?

Ja, Dropzone v5 har innebygd støtte for oppdelt opplasting via innstillingene chunking: true, chunkSize (i byte) og forceChunking. Tjeneren må kunne sette sammen biter: motta hver del med headere dzchunkindex og dztotalchunkcount, lagre dem midlertidig og slå dem sammen etter å ha mottatt den siste. Et ferdig PHP-eksempel for sammensetting av biter finnes i Dropzone-repositoriet.

Hvordan fjerner jeg en filforhåndsvisning etter vellykket opplasting?

Kall myDropzone.removeFile(file) i hendelsesbehandleren for success. Filen forsvinner fra grensesnittet, men forblir på tjeneren. Hvis du også trenger å slette den fra tjeneren, legg til et AJAX-kall i samme behandler før removeFile.

Er Dropzone kompatibelt med WordPress?

Ja, biblioteket kan inkluderes via wp_enqueue_script() i ditt tema eller din plugin. Et typisk WordPress-scenario: erstatte standard medieopplaster på en egendefinert administrasjonsside eller et frontend-skjema. Du trenger bare å angi riktig behandler-URL, vanligvis admin_url('admin-ajax.php') med en registrert AJAX-handling.

Er Dropzone.js riktig for ditt prosjekt

Hvis du trenger dra-og-slipp-filopplasting «her og nå», løser Dropzone.js oppgaven raskere enn noen egenskrevet kode. Her er fem grunner til at biblioteket fortsatt er relevant i 2026:

  • Ingen avhengigheter. Ikke jQuery, Bootstrap eller React. Inkluder én JS-fil, så fungerer det.
  • Nettleserstøtte på tvers. Støtter nettlesere ned til IE11 og degraderer elegant uten JavaScript.
  • Ferdig visualisering. Bildeforhåndsvisninger, fremdriftslinjer, suksess-/feilikoner rett ut av boksen, uten CSS-layoutarbeid.
  • Dokumentasjon. Oppdatert GitBook og et aktivt GitHub-repositorium (1 700+ stjerner per 2026).
  • Fleksibilitet. Fra enkel bildeskalering før opplasting til oppdelt opplasting av gigabyte-store filer, alt er konfigurerbart.

Når Dropzone ikke er det beste valget: hvis du allerede bruker React/Vue og ønsker en naturlig komponent uten ekstern DOM-manipulasjon. React-økosystemet har react-dropzone, Vue har vue-dropzone. Men for vanilla JavaScript, jQuery-prosjekter og WordPress-nettsteder er Dropzone.js et velprøvd verktøy som ikke vil svikte deg.

Praktisk integrasjonseksempel. Ett typisk WordPress-scenario: en «Last opp dokumenter»-side i en klientportal. Brukeren drar inn skanninger av pass, kontrakt og eiendomsbilder. Dropzone inkluderes via wp_enqueue_script() i temaets functions.php, og behandleren er en egendefinert AJAX-handling registrert via wp_ajax_nopriv_. Hver vellykket opplastet fil legges til mediebiblioteket via wp_insert_attachment(), og dens ID lagres i brukermeta. Hele frontend-koden får plass på 30 linjer, og tjenersiden på 50. Til sammenligning ville en egenskrevet dra-og-slipp med samme funksjonalitet tatt 400-600 linjer JavaScript og 2-3 dagers utvikling.

Når det gjelder alternativer: Uppy (fra skaperne av Transloadit) tilbyr en modulær arkitektur med plugins for React, Svelte og S3-opplastinger, men krever flere avhengigheter og mer konfigurasjon. Fine Uploader har ikke vært vedlikeholdt siden 2018; det finnes forgreninger, men uten sikkerhetsgarantier. Dropzone.js vinner på balansen mellom «funksjonalitet per kompleksitetsenhet»: én fil, minimal konfigurasjon og synlige resultater fem minutter etter integrasjon.

Noen tilleggsfunksjoner det er verdt å kjenne til før du starter. Dropzone tilbyr en full hendelsessyklus: addedfile, thumbnail, uploadprogress, complete og queuecomplete. Den siste er spesielt nyttig: den utløses når alle filer i køen er behandlet, slik at du kan vise brukeren en oppsummeringsmelding eller omdirigere til en annen side. Ved nettverksfeil finnes det innebygd nytt forsøk: ved en opplastingsfeil viser Dropzone en «Prøv igjen»-knapp ved siden av filforhåndsvisningen, og nytt forsøk går gjennom samme behandler uten kodeduplisering. Grensesnittet er fullt lokaliserbart via dict-innstillinger: dictCancelUpload, dictRemoveFile, dictMaxFilesExceeded og omtrent to dusin nøkler til. Norsk språkstøtte settes opp på fem minutter ved å kopiere et objekt fra dokumentasjonen. Biblioteket veier 28 KB komprimert (gzip), noe som legger til under 0,1 sekunder til sidens lastetid på mobil 4G. Alle disse funksjonene gjør Dropzone.js til de facto-standarden for dra-og-slipp-opplasting i prosjekter uten rammeverk: én million npm-nedlastinger per uke i starten av 2026, og bruk i WordPress-, Laravel- og Symfony-administrasjonspaneler.