Drag and Drop Upload mit HTML5

Wenn wir uns moderne Webseiten oder Content Management Systeme wie WordPress anschauen finden wir für Uploads immer öfter die Möglichkeit, Dateien einfach per Drag and Drop in den Browser zu ziehen und einen Live-Upload durchzuführen. Dadurch ersparen wir dem Besucher das lästige durchsuchen des Dateisystems und erlauben auch mehrere Uploads gleichzeitig. Außerdem können wir ein Livefeedback einbauen, wie weit der Upload bereits fortgeschritten ist.

Was benötigen wir alles für den Upload?

Zuerst benötigen wir ein HTML Element, auf das der Besucher seine Dateien ziehen kann. Dieses wird mit einem JavaScript drop Event versehen, welches eine Callback Funktion aufruft, sobald dies geschieht. Diese Funktion erhält eine Liste mit den Dateien, die dann ausgelesen werden können und per AJAX Request an den Webserver gesendet werden. Dort kann mithilfe von PHP der Upload verwertet werden. Über zusätzliche Callback Funktionen können wir außerdem den Uploadfortschritt dokumentieren und zum Beispiel eine Prozentangabe oder sogar einen Fortschrittsbalken darstellen.

Soviel zur Theorie, wenden wir uns der Praxis zu.

Schritt 1: Das HTML Gerüst

Unser HTML Gerüst besitzt nicht viele Voraussetzungen. Es muss einen Container geben, auf den das drop Event gelegt werden kann. Für mehr Feedback kann dieser Container natürlich mit CSS schön hervorgehoben werden und mit einem hover-Effekt versehen werden, der dem User anzeigt, was passiert.

Soweit so gut. Mit diesem Gerüst bieten wir dem Besucher die Möglichkeit, seine Dateien in den Browser zu ziehen und zeigen auch den Gesamtfortschritt des Uploads an. Machen wir nun mit dem ersten JavaScript Teil weiter – das drop Event.

 

Schritt 2: Das drop Event

Der nächste Schritt liegt darin, überhaupt mitzubekommen, wenn Dateien auf unsere dropzone gezogen werden. Dafür bietet JavaScript uns das drop Event an. Wir fügen also einen EventListener hinzu, der auf das drop Event horcht:

Als Callbackfunktion definieren wir die Funktion handleDropEvent. Diese erhält das Eventobjekt als Parameter, welches auch eine Liste mit den Dateien enthält, die der User hochladen möchte.

Neben dieser Funktion benötigen wir noch einige globale Variablen. Für den Anfang sieht unsere upload.js Datei also so aus:

 

Schritt 3: Eine Datei hochladen

Als nächstes kümmern wir uns darum, dass unsere Liste mit hochzuladenden Dateien abgearbeitet wird – eine Datei nach der anderen. Dafür definieren wir zwei Funktionen:

  • startNextUpload() überprüft die nächste Datei in der Liste
  • uploadFile() sendet eine Datei an den Server

In der startNextUpload() Funktion besteht die Möglichkeit, Dateien auch noch grundlegend zu validieren (zum Beispiel Maximalgröße).

Die uploadFile() Funktion enthält dann den XMLHttpRequest, der die Datei an den Server sendet – in diesem Fall an die upload.php, die wir als nächstes mit Inhalt füllen.

 

Schritt 4: Die Serverseite

Natürlich müssen wir auch auf unserem Webserver auf die Uploads reagieren. Das folgende Script erledigt hier nur die Grundlagen und muss natürlich für eine Liveversion noch um Dinge wie Sicherheit, Validierung und ähnliches erweitert werden.

 

Schritt 5: Weitere Events

Abschließend müssen wir uns noch um einige weitere Events kümmern, die bei unserem XMLHttpRequest auftreten können. Schließlich muss nach einem abgeschlossenen Upload der nächste gestartet werden und wir wollen unserem Besucher ja auch zeigen, wieviel schon geschafft ist. Zu diesem Zweck erweitern wir unsere uploadFile() Funktion noch um drei Eventlistener und definieren die dazu passenden Callbackfunktionen handleComplete(), handleError() und handleProgress().

Zuerst die Definition der drei Funktionen:

 

Und nun weisen wir diese Callbacks noch den jeweiligen Events zu. Dafür erweitern wir unsere uploadFile() Funktion um folgenden Abschnitt:

 

Damit wissen wir nun, wie wir unseren eigenen Fileupload schreiben können, den wir genau auf unsere Bedürfnisse anpassen. Soll es flexibler (und natürlich auch viel einfacher) sein können wir auch ein fertiges Script wie zum Beispiel Dropzone verwenden und auf unsere Bedürfnisse anpassen.

8 Kommentare zu “Drag and Drop Upload mit HTML5

  1. Hallo Frank, kannst du mir sagen, wie ich einrichte, dass ich per drag and drop einen file an meinen rest-server, der cherrypy benutzt, schicken kann, um dann den file dort abzuspeichern?

    • Hi Till,

      leider kenne ich mich mit CherryPy (oder allgemein Python) überhaupt nicht aus. Allerdings sollte das Prinzip dasselbe sein wie bei allen serverseitigen Sprachen, das heißt du hast einen Request, der deine Daten enthält (also die Datei die du hochladen möchtest) und empfängst diese Daten dann auf dem Server (in deinem Fall mit Python, das ist der Teil den du selbst rausfinden müsstest :)).
      Clientseitig musst du dabei einerseits dafür sorgen, dass du die richtige URL mit dem Request ansteuerst und andererseits, dass das richtige HTTP Verb (also POST z.B.) verwendet wird. Und natürlich die Datei mitsenden 🙂

      Viel Grüße
      Frank

  2. Mir sind zwei „Fehler“ aufgefallen, wobei durch einen das Ganze überhaupt nicht funktionieren kann.
    in function handleDropEvent wird keine function ausgeführt, die überhaupt den Upload startet.
    Des Weiteren erhalte ich, nachdem ich „startNextUpload“ innerhalb der for-Schleife in der function handleDropEvent mit reinnehme „Uncaught TypeError: Cannot read property ’size‘ of null“ in der function „handleComplete“ an der Stelle totalProgress += currentUpload.size;
    -> Hat zur Folge, dass meine Progressbar bei drei Datein auf 2/3 stehen bleibt.

  3. Hallo Frank,
    das ist wirklich eine klasse Anleitung. Leider habe ich ein Problem.
    Wenn ich eine Datei auf dem Feld dropen will, dann wird es geöffnet anstatt dass das JavaScript ausgeführt wird.
    Muss ich in der .js noch etwas beachten das ich vielleicht vergessen habe?

  4. Hallo, ich habe den code genau so eingefügt wie hier beschrieben, leider passiert da garnichts ausser das das bild auf der seite angezeigt wird aber direkt von der festplatte als würde ich ein bild einfach dort hin ziehen. was mache ich falsch?

  5. Hi Frank,
    dito München. Wühle mich gerade durch Dein Tutorial und freue mich, dass jemand ohne das doofe jQuery arbeitet. Danke für Deine Mühe.
    Es wäre interessant, mal den kompletten Code zu sehen. Ein paar Issues:
    – handleError oder errorHandler, wie heißt die Funktion denn nun?
    – event.stopPropagation(); event.preventDefault(); das sollte nicht nur bei ‚drop‘, sondern auch bei ‚dragenter‘ und ‚dragover‘ aufgerufen werden, sonst wird einfach die gedroppte Datei angezeigt (Firefox Dev Edition 55)
    – wann, wie werden startNextUpload() und uploadFile() denn aufgerufen?
    So, weiter bin ich noch nicht.
    LG aus Neuhausen,
    Jan

  6. Hallo Frank,
    dieser Artikel ist toll aufgebaut, jeder Baustein wird erklärt…
    Allerdings nützt er nur denen, die Das Thema schon beherrschen. Jemand wie ich, der an einem Beispiel lernen möchte, kommt aber beim Zusammenfügen der Einzelabschnitte in’s Straucheln. Ich habe jetzt die 3 Dateien (HTML-Teil, upload.js und upload.php) in einem Verzeichnis erstellt, aber trotz aller Bemühungen tut sich nichts. Der Fehler liegt sicherlich irgendwo im JS.
    Ist es nicht möglich, wenigstens für die upload.js ein komplettes Script abzubilden? Manchmal wird wohl übersehen, daß ein Lernender nicht alles überblicken kann, eben weil er noch lernt…
    Freundliche Grüße
    Henning

  7. Hi Frank, coole Anleitung,

    aber ich habe es versucht, lokal auf meinen Server installieren, also 3 Dateien, html php und die js.
    Aber irgendwie flutsch das nicht, weiß nicht warum.
    Gibt es dann keine Zusammenfassung zum Download alle 3 Dateien?

    ziehe ich ein Bild rein zeigt mein Browser ist immer als Bild an.

    Getestet auf ie11 und Firefox 58

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*