JavaScript/File Upload

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Mit der HTML5 File Upload API kommt nun eine neue Möglichkeit, Dateien vom heimischen Rechner auf einen Webserver hochzuladen.[1]

  • HTML5
  • Chrome
  • Firefox
  • IE 10
  • Opera
  • Safari

Details: caniuse.com

Interessant ist hierbei vor allem, dass die APIs die Möglichkeit bieten den Uploadfortschritt zu verfolgen, Thumbnails (Miniaturansichten) der Dateien anzuzeigen, sowie der Einsatz von Drag and Drop. Letzteres ist sehr bequem um Dateien vom Desktop oder aus Ordnern direkt in die Webanwendung zu ziehen, in die die Datei geladen werden soll.


Multi Upload von Dateien[Bearbeiten]

Beispiel ansehen …
  function dateiauswahl(evt) {
    var files = evt.target.files; // FileList object

    //Deklarierung eines Array Objekts mit Namen "output" Speicherung von Eigenschaften
    var output = [];
    //Zählschleife, bei jedem Durchgang den Namen, Typ und die Dateigröße der ausgewählten Dateien zum Array hinzufügen
    for (var i = 0, f; f = files[i]; i++) {
      output.push('<li><strong>', f.name, '</strong> (', f.type || 'n/a', ') - ',
                  f.size, ' bytes</li>');
    }
    //Auf das Ausgabefeld zugreifen, unsortierte Liste erstellen und das oben erstellte Array auslesen lassen
    document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
  }
  //Falls neue Eingabe, neuer Aufruf der Auswahlfunktion
  document.getElementById('files').addEventListener('change', dateiauswahl, false);

Für die Auswahl von Dateien eignet sich ein input type="file" besonders, das hier bereitgestellt wird. Die neue Option multiple sorgt dabei dafür, dass auch wirklich mehrere Dateien ausgewählt werden können. Anschließend wird in der Funktion dateiauswahl() ein Array output angelegt. In diesem Array werden mittels einer Zählschleife für jede ausgewählte Datei deren Dateiname, -typ, sowie Größe gespeichert (über die Arraymethode push()).

Zusätzlich werden vor und hinter den Dateiattributen <li> und <strong>Tags mitgespeichert, die bei der Ausgabe für eine schönere Ansicht sorgen. Dies ist natürlich kein Muss.

document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>'; sorgt dafür, dass auf das output-Element zugegriffen wird und in diesem eine ungeordnete Liste mittels <ul>...</ul> erzeugt wird und in diesem mittels der Arraymethode join() die Einträge aus dem output-Array ausgelesen werden. Durch die mitgespeicherten <li>-Tags werden nun die Werte als Listenelemente dargestellt und durch die <strong> tags fett formatiert.

Auswahl mit Drag und Drop[Bearbeiten]

Beispiel ansehen …
  function dateiauswahl(evt) {
    evt.stopPropagation();
    evt.preventDefault();

    var gewaehlteDateien = evt.dataTransfer.files; // FileList Objekt


    var output = [];
    for (var i = 0, f; f = gewaehlteDateien[i]; i++) {
      output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
                  f.size, ' bytes, last modified: ',
                  f.lastModifiedDate.toLocaleDateString(), '</li>');
    }
    document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
  }

  function handleDragOver(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    evt.dataTransfer.dropEffect = 'copy'; 
  }

  // Initialisiere Drag&Drop EventListener
  var dropZone = document.getElementById('dropzone');
  dropZone.addEventListener('dragover', handleDragOver, false);
  dropZone.addEventListener('drop', dateiauswahl, false);

Hier können Sie Bilder und Dateien aus Ihrem Betriebssystem bequem mit der Maus (Drag & Drop) ziehen und im div mit der id dropzone ablegen.

Anschließend wird die ausgewählte Datei wie im Beispiel 1 mit einigen Eigenschaften aufgelistet.

Direkter Upload einer einzelnen Datei an einen Server[Bearbeiten]

Beispiel
  function dateiupload(evt) {
    var dateien = evt.target.files; // FileList objekt

    // erste Datei auswählen (wichtig, weil IMMER ein FileList Objekt generiert wird)
    var uploadDatei = dateien[0];

    // Ein Objekt um Dateien einzulesen
    var reader = new FileReader();

    var senddata = new Object();
    // Auslesen der Datei-Metadaten
    senddata.name = uploadDatei.name;
    senddata.date = uploadDatei.lastModified;
    senddata.size = uploadDatei.size;
    senddata.type = uploadDatei.type;

    // Wenn der Dateiinhalt ausgelesen wurde...
    reader.onload = function(theFileData) {
      senddata.fileData = theFileData.target.result; // Ergebnis vom FileReader auslesen

      /*
      Code für AJAX-Request hier einfügen
      */
    }

    // Die Datei einlesen und in eine Data-URL konvertieren
    reader.readAsDataURL(uploadDatei);
  }

Dank der Möglichkeit, eine Datei als Data-URL einzulesen, ist es möglich, selbst mit einem gewöhnlichen Webformular eine Datei an einen Server zu senden.

Beachten Sie: Um die Datei auf dem Server abzuspeichern, muss dieser "nur" den Base64-kodierten Teil der Daten-URL wieder in seinen ursprünglichen Bytecode zurückkonvertieren. Der Datentyp, der der Daten-URL beigefügt wird, dient dabei als doppelte Absicherung, um Betrugsfälle abzuwehren.

Auswahl mit Bildvorschau[Bearbeiten]

Beispiel ansehen …
  function dateiauswahl(evt) {
    var dateien = evt.target.files; // FileList object

    // Auslesen der gespeicherten Dateien durch Schleife
    for (var i = 0, f; f = dateien[i]; i++) {

      // nur Bild-Dateien
      if (!f.type.match('image.*')) {
        continue;
      }

      var reader = new FileReader();

      reader.onload = (function(theFile) {
        return function(e) {
          // erzeuge Thumbnails.
          var vorschau = document.createElement('img');
		  vorschau.className = 'thumb';
		  vorschau.src   = e.target.result;
		  vorschau.title = theFile.name;
          document.getElementById('list').insertBefore(vorschau, null);
        };
      })(f);

      // Bilder als Data URL auslesen.
      reader.readAsDataURL(f);
    }
  }
  // Auf neue Auswahl reagieren und gegebenenfalls Funktion dateiauswahl neu ausführen.
  document.getElementById('files').addEventListener('change', dateiauswahl, false);

In diesem Beispiel werden von den hochzuladenden Bildern Vorschaubilder erstellt (Thumbnailing), die dann im Ausgabefeld output-Element angezeigt werden.

Beachten Sie: Textdateien werden nicht dargestellt.

Auswahl mit Textvorschau[Bearbeiten]

Beispiel
  function dateiauswahl(evt) {
    var dateien = evt.target.files; // FileList object

    // Auslesen der gespeicherten Dateien durch Schleife
    for (var i = 0, f; f = dateien[i]; i++) {

      // nur TXT-Dateien
      if (!f.type.match('text/plain')) {
        continue;
      }

      var reader = new FileReader();

      reader.onload = (function(theFile) {
        return function(e) {
          // erzeuge "Thumbnails"
          var vorschau = document.createElement('p');
		  vorschau.className = 'thumb';
		  vorschau.src   = e.target.result;
		  vorschau.title = theFile.name;
          document.getElementById('list').insertBefore(vorschau, null);
        };
      })(f);

      // Klartext mit Zeichenkodierung UTF-8 auslesen.
      reader.readAsDataText(f, utf8);
    }
  }
  // Auf neue Auswahl reagieren und gegeenenfalls Funktion dateiauswahl neu ausführen.
  document.getElementById('files').addEventListener('change', dateiauswahl, false);

In diesem Beispiel wird von den hochzuladenden Texten der komplette Inhalt übernommen, welcher dann im Ausgabefeld output-Element angezeigt wird.

Beachten Sie: Diese Methode ist nur für TXT-Dateien sinnvoll.
Beachten Sie: Sie müssen bereits im Vorfeld die exakte Zeichenkodierung der Textdateien kennen. Wird die Angabe weggelassen, wird die Datei mit der Zeichenkodierung UTF-8 ausgelesen.

(billiger) Hex-Viewer im Browser[Bearbeiten]

Beispiel
  function dateiauswahl(evt) {
    var dateien = evt.target.files; // FileList object

    // Auslesen der gespeicherten Dateien durch Schleife
    for (var i = 0, f; f = dateien[i]; i++) {

      var reader = new FileReader();

      reader.onload = (function(theFile) {
        return function(e) {
          // Bytedaten übernehmen
          var byteBlock = e.target.result;  // ArrayBuffer Objekt
          // ein Objekt um den Byteblock auszulesen
          var dataViewer = new DataView(byteBlock);
          var hexView = "";
          // Hex-Werte übernehmen
          for (var j = 0; j < f.size; j++) {
            hexView += parseInt(dataViewer.getUint8(j), 16) + " ";
          }
          // Das Leerzeichen am Ende entfernen
          hexView = hexView.substr(0,hexView.length-1);
          // erzeuge "Thumbnails"

          var vorschau = document.createElement('p');
		  vorschau.className = 'thumb';
		  vorschau.src   = hexView
		  vorschau.title = theFile.name;
          document.getElementById('list').insertBefore(vorschau, null);
        };
      })(f);

      // Datei als ByteArray auslesen auslesen.
      reader.readAsArrayBuffer(f);
    }
  }
  // Auf neue Auswahl reagieren und gegebenenfalls Funktion dateiauswahl neu ausführen.
  document.getElementById('files').addEventListener('change', dateiauswahl, false);

Hiermit können die Hexwerte jeder beliebigen Datei ausgelesen werden.

Beachten Sie: Das DataView-Objekt ist so mächtig, dass man hiermit einen voll funktionsfähigen Hex-Editor im Browser erstellen kann. Daher sollte der Gebrauch des ArrayBuffer- und des DataView-Objekts mit Vorsicht genossen werden.

Weblinks[Bearbeiten]

  1. W3C: File Upload API