CSS, HTML und Javascript mit {stil}

Ajax 2 – Dateien laden mit Fortschrittsbalken

Session Storage

Javascript bringt handfeste Verbesserungen des XMLHttp-Requests. Mit Ajax 1 stand nur ein Event zur Verfügung: onreadystatechange. Ajax 2 beschert uns ein neues Event-Modell mit neuen Events, die eine detailliertere Abfrage der Vorgänge und des Zustands erlauben.

Mit Ajax 2 kann ein Post Back zu einem Ajax-Server auf einer anderen Domain durchgeführt werden – Cross Origin Requests

Wie glücklich kleine Fortschritte machen – mit HTML5 und Ajax 2 kommt endlich ein Fortschrittsbalken.

progress – Fortschrittsbalken

HTML5 hat dafür das progress-Tag spendiert, das mit Javascript in Gang gesetzt wird.

Mehrere Dateien laden

Dass die Thumbnails für die geladenen Bilder hier so schnell erscheinen, liegt natürlich daran, dass sie noch nicht auf den Server geladen sind, sondern noch im Speicher des Browsers liegen.

Erst wenn die Formulardaten mit dem "Laden"-Button abgeschickt werden, beginnt der Upload auf den Server.

<form action="…">
   <input type="file" id="file" multiple="true" accept="image/*" />
   <button id="startUpload">Laden</button>
   <progress id="progress" value="0" max="100"></progress>
   <span id="msg"></span>
</form>

Ajax: Upload mehrerer Dateien

Die Auswahl mehrerer Dateien für den File-Upload war bislang dem File-Upload mit Flash vorbehalten oder einem komplexen Ajax-Ablauf.

In HTML5 hat das input-Tag für den File-Upload ein neues Attribut multiple="true" und ohne großen Aufwand kann Ajax 2 mehrere Dateien auf den Server laden.

Mobile Geräte wie Tablet oder Smartphone bieten den Upload von Dateien aus dem Album des Geräts an. multiple="true" funktioniert allerdings nicht, wenn Bilder aus der Kamera geladen werden sollen.

Fotos aus der Kamera werden mit

	<input type="file" accept="image/*" capture="camera" />

geladen. Das funktioniert zurzeit allerdings nur mit Webkit-Browsern (Chrome, Safari).

doStartUpload() lädt die ausgewählten Dateien in den Speicher des Browsers, genauer gesagt, in das Javascript FileReader()-Objekt.

document.getElementById('startUpload').addEventListener ('click',doStartUpload,true);
var msg = document.getElementById('msg');
var progress = document.getElementById('progress');

function doStartUpload (e) {
  progress.value = 0;
  msg.innerHTML = '';
  document.querySelector ('#dlist').innerHTML = '';
  var fileElem = document.getElementById('file');
  if (fileElem.files.length == 0) {
    msg.innerHTML = 'Wählen Sie zuerst eine Datei aus';
  } else {
    msg.innerHTML = 'Datei für Übertragung vorbereiten … ';
    var reader = new FileReader();
    reader.onloadend = doUpload;
    reader.readAsArrayBuffer(fileElem.files[0]);
    // Um mal zu sehen, was im Browser landet … 
    for (var i = 0, f; f = fileElem.files [i]; i++ ) {
      document.querySelector ('#dlist').innerHTML += 
        f.size + ' ' +  
        f.type + '<br />'; 
    }
  }
  e.preventDefault();
}

upload.onprogress und onprogress

Ein Fortschrittsbalken für den Upload von Dateien ist ein wichtiges Element der Benutzeroberfläche.

Javascript konnte zwar den Dateinamen, den Dateityp sowie Höhe und Breite des Bildes lesen, aber hatte keinen Zugriff auf die Größe der Datei auf dem lokalen Rechner des Benutzers.

function doUpload(e) {
   var xhr = new XMLHttpRequest();
   xhr.upload.onprogress = function (e) {
      var percentUpload = Math.floor(100*e.loaded / e.total);
      progress.value = percentUpload;
      msg.innerHTML = percentUpload + '% geladen';
   }

   xhr.onerror = function(e) {
      msg.innerHTML = "Ein Fehler ist aufgetreten";
   }

   xhr.open ('POST', targetLocation, true); // XMLRequest an den Server
  
   var bytesToSend = [253, 0, 128, 1],
      bytesArray = new Uint8Array(bytesToSend);

   xhr.setRequestHeader('Content-Type', 'application/octet-stream');
   xhr.send(bytesArray);
}