Ajax Fileupload Fortschrittsanzeige

Zugriffe: 5793 starstarstarstarstarstarstarstarstarstar Bewertung:2,86 (14 Bewertungen) 05.06.2009

Wer sich mit dem Fileupload beschäftigt, steht irgendwann vor dem Problem, wie denn die Fortschrittsanzeige im Webbrowser sich umsetzen lässt.
Die Hardcorelösung wäre, den Benutzer auf die Anzeige in der Browserstatusanzeige zu verweisen. Die inzwischen häufigste Variante des Fileuploads besteht darin, für das Versenden der Datei ein iframe-Element zu verwenden. Zwar wird mitunter durch den Browser visuell signalisiert, dass sich da etwas tut, doch bekommt das der Benutzer jetzt noch weniger mit, wie beim Full-Postback der Seite.

Immer wieder trifft man im Netz auf Lösungen, die für die Zeit des Uploads eine animierte Grafik einblenden. Andere wiederum berechnen einen Uploadfortschritt auf Basis des für die Darstellung zur Verfügung stehenden Containers. Ist das Ende des Containers erreicht, fängt die Fortschrittsanzeige wieder von vorn an.

Worin besteht das Problem? Das iframe kann den Benutzer in der Regel informieren über den onload Event - doch dann hat aller Spuck oft ein Ende. Im Rahmen dieses Events beenden die meisten Entwickler die Darstellung ihrer Uploadanimationen.

Angeregt durch die Möglichkeiten, welche die Flashprogrammierung einem offenbaren, wollte ich einen halbwegs realistischen Uploadfortschritt im HTML mit Javascript realisieren. So suchte ich nach den Dingen, die mir letztlich zur Verfügung standen. Das waren

  • das iframe
  • der Uploadhandler (das document)

Für das document gibt es die Eigenschaft readyState - die, wie sollte es auch anders sein - kein Standard ist. Aber welche Informationen bietet mir diese Eigenschaft? Solange das document geladen wird ist der Wert loading oder (beim Opera-Browser) - interactive. Beide haben aber den Wert complete, wenn das document vollständig übertragen ist. Webbrowser, die diese Eigenschaft nicht unterstützen, muss man dann etwas austricksen. Nun braucht man eigentlich nur noch dafür zu sorgen, dass dieser Status regelmäßig geprüft wird. Die folgende Javascript-Methode zeigt einen möglichen Ansatz:

var iframeProgress = function(iframe, state, percent) {
    try {
          if (iframe[0].contentWindow) {
            var doc = iframe.contents();
            if (doc != undefined && doc.length == 1) {
                 var newstate = $.browser.msie ? doc[0].readyState : "loading";
                 if (newstate != state && newstate != "complete") {
                    if (percent < 98) {
                        // hier die Progressanzeige aktualisieren
                        setTimeout(function() { iframeProgress(iframe, state, percent += 2); }, 400);
                    }
                  }
             }
           }
        } catch (ex) { }
}

In dem Moment, wo der submit Event der Form getriggert wird, wird mit einer kleinen Verzögerung die Methode iframeProgress aufgerufen, der als Parameter das iframe-(jQuery)Objekt, der Status und die aktuellen Prozentwerte der übertragung mit übergeben werden. Das der Firefox z.B. die readyState - Eigenschaft nicht kennt, schiebe ich ihm diese einfach unter. Die Prüfung auf den Wert complete wird der Firefox ebenso nicht anders beantworten können, so dass die Prozentzahl um 2 erhöht und die Methode erneut aufgerufen wird. Dies passiert so lange, bis der onload Event des iframe selbst ausgelöst wird oder der fiktive Prozentwert 98 erreicht ist. Ich habe das Szenario mit Uploadgrößen von bis zu 47 MB getestet. Die Variation der Fortschrittsanzeige besteht im Verändern des Timeoutwertes und der Schrittweite des Hochzählens des Prozentwertes.

uploadprogress

Am Ende kann man aber auf diesem Wege eine halbwegs realistische Fortschrittsanzeige im HTML mit Javascript realisieren.


2 Kommentare
Andre Loker Andre Loker Sonntag, 7. Juni 2009
Danke für die Info, werde ich beim nächsten Mal, wenn ich File upload benötige, mal ausprobieren.

Grüße,
Andre

P.S.: Dein Kommentarformular reagiert im FF sehr seltsam auf Tabs...
Rene Rene Sonntag, 7. Juni 2009
Hallo Andre,

das Problem mit den Tabs (tabindex) ist noch nicht ganz gelöst, es hat aber nichts mit dem Browser zu tun, sondern mit dem Rendern der Seite (dynamische Inhalte). Ich werde den TabIndex demnächst über eine Session verwalten, so dass das Problem behoben sein sollte.

Gruß
Rene

Neuen Kommentar verfassen

Bestätigungscode