René 's Weblog
...und was die Welt schon immer nicht wissen wollte
Ajax Fileupload Fortschrittsanzeige
Zugriffe:2110Bewertung:3,33(3Bewertungen)05.06.2009 - René Drescher-Hackel
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.
Kick it on dotnet-kicks.de
sehr gutungenügend

Andre LokerKommentar von Andre Loker am 07.06.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...
ReneKommentar von Rene am 07.06.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
Ihr Kommentar zu diesem Beitrag:
your gravatar
Sollten die Eingabefelder deaktiviert sein, so aktualisieren Sie den Bestätigungscode.
Best&auml;tigungscode
Das Weblog von René Drescher-Hackel beschäftigt sich überwiegend mit Themen aus dem Bereich der Webanwendungsentwicklung mit den Themenschwerpunkten ASP.NET und C# im DOT-NET Framework 2.0 / 3.5. In der clientseitigen Entwicklung liegt der Schwerpunkt bei Javascript und jQuery. René; Drescher-Hackel hat die Prüfung zum Microsoft Certified Tecnology Specialist - .NET Framework 2.0 Web Applications abgelegt.