Warum kennen einige Download-Dateien nicht ihre eigene Größe? [Duplikat]

82

Diese Frage hat hier bereits eine Antwort:

Gelegentlich "kennt" der Download-Fortschritt beim Herunterladen einer Datei in einem Webbrowser nicht die Gesamtgröße der Datei oder wie weit der Download fortgeschritten ist - er zeigt lediglich die Geschwindigkeit an, mit der die Datei heruntergeladen wird Insgesamt als "Unbekannt".

Warum konnte der Browser die endgültige Größe einiger Dateien nicht ermitteln? Woher bekommt es diese Informationen überhaupt?

Kaltschwarz
quelle
13
Dynamisch erstellte Dateien haben keine Größe, sie werden als Stream übertragen, bis EOF erreicht ist.
Fiasko Labs

Antworten:

114

Um Dokumente von Webservern anzufordern, verwenden Browser das HTTP-Protokoll. Möglicherweise kennen Sie diesen Namen aus Ihrer Adressleiste (möglicherweise ist er jetzt ausgeblendet. Wenn Sie jedoch auf die Adressleiste klicken, die URL kopieren und in einen Texteditor einfügen, wird dies http://am Anfang angezeigt ). HTTP ist ein einfaches textbasiertes Protokoll. Das funktioniert so:

Zunächst stellt Ihr Browser eine Verbindung zum Server der Website her und sendet eine URL des herunterzuladenden Dokuments (auch Webseiten sind Dokumente) sowie einige Details zum Browser selbst ( User-Agent usw.). Um beispielsweise die Hauptseite auf der SuperUser-Site zu laden http://superuser.com/, sendet mein Browser eine Anfrage, die folgendermaßen aussieht:

GET / HTTP/1.1
Host: superuser.com
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.0 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: [removed for security]
DNT: 1
If-Modified-Since: Tue, 09 Jul 2013 07:14:17 GMT

Die erste Zeile gibt an, welches Dokument der Server zurückgeben soll. Die anderen Zeilen heißen Überschriften; sie sehen so aus:

Header name: Header value

Diese Zeilen senden zusätzliche Informationen, anhand derer der Server entscheiden kann, was zu tun ist.

Wenn alles in Ordnung ist, sendet der Server das angeforderte Dokument. Die Antwort beginnt mit einer Statusmeldung, gefolgt von einigen Kopfzeilen (mit Details zum Dokument) und schließlich, wenn alles in Ordnung ist, dem Inhalt des Dokuments. So sieht die Antwort des SuperUser-Servers auf meine Anfrage aus:

HTTP/1.1 200 OK
Cache-Control: public, max-age=60
Content-Type: text/html; charset=utf-8
Expires: Tue, 09 Jul 2013 07:27:20 GMT
Last-Modified: Tue, 09 Jul 2013 07:26:20 GMT
Vary: *
X-Frame-Options: SAMEORIGIN
Date: Tue, 09 Jul 2013 07:26:19 GMT
Content-Length: 139672

<!DOCTYPE html>
<html>
    [...snip...]
</html>

Nach der letzten Zeile schließt der SuperUser-Server die Verbindung.

Die erste Zeile ( HTTP/1.1 200 OK) enthält den Antwortcode , in diesem Fall ist es 200 OK. Dies bedeutet, dass der Server entschieden hat, dass er ein Dokument wie angefordert zurückgeben kann, und verspricht, dass der folgende Inhalt ein solches Dokument sein wird. Ist dies nicht der Fall, handelt es sich bei dem Code um einen anderen Code, und er gibt einen Hinweis darauf, warum der Server ein Dokument nicht nur als Antwort zurückgibt. Wenn er beispielsweise das angeforderte Dokument nicht findet, soll er es zurückgeben 404 Not Found, und wenn Sie nicht auf den fraglichen Inhalt zugreifen dürfen, soll er zurückkehren 403 Forbidden.

Nach dieser ersten Statuszeile folgen die Antwortheader. Sie bieten weitere Informationen zum zurückgegebenen Inhalt, z Content-type.

Weiter ist eine leere Zeile. Es signalisiert, dass keine Antwortheader mehr folgen. Alles, was über diese Zeile hinausgeht, ist der Inhalt des angeforderten Dokuments. Im obigen Beispiel <!DOCTYPE html>ist dies die erste Zeile der SuperUser-Homepage (ein HTML-Dokument). Wenn ich ein Dokument zum Herunterladen anfordere, handelt es sich wahrscheinlich um einige Kauderwelschzeichen, da die meisten Dokumentformate ohne vorherige Verarbeitung nicht lesbar sind.

Zurück zu den Überschriften. Das interessanteste für uns ist das letzte Content-Length. Es teilt dem Browser mit, wie viele Datenbytes nach der Leerzeile erwartet werden sollen. Im Grunde genommen handelt es sich also um die in Bytes ausgedrückte Dokumentgröße. Dieser Header ist nicht obligatorisch und kann vom Server weggelassen werden. Manchmal kann die Dokumentgröße nicht vorhergesagt werden (zum Beispiel, wenn das Dokument im laufenden Betrieb erstellt wird), manchmal wird es von faulen Programmierern nicht berücksichtigt (was bei Websites zum Herunterladen von Treibern häufig vorkommt), manchmal werden Websites von Neulingen erstellt, die es nicht wissen von einem solchen Header.

Egal aus welchem ​​Grund, der Header kann fehlen. In diesem Fall weiß der Browser nicht, wie viele Daten der Server senden wird, und zeigt daher die Dokumentgröße als unbekannt an , während er darauf wartet, dass der Server die Verbindung schließt. Und das ist der Grund für unbekannte Dokumentengrößen.

gronostaj
quelle
4
Eine sehr, sehr kleine Anmerkung: Browser unterstützen andere Protokolle als HTTP. Aber andere Protokolle sind heutzutage selten und im Wesentlichen gelten die gleichen Konzepte für andere Protokolle, auch wenn die Details unterschiedlich sind.
Robert Fisher
5
@RobertFisher FTP ist ein seltenes Protokoll? : p
Thomas
5
@ Thomas Das ist meine Erfahrung in diesen Tagen. Es ist einige Jahre her, dass ich in meinem Browser eine FTP-URL gefunden habe. Vor ein paar Jahren habe ich ftp bei der Arbeit verwendet - direkt und nicht mit einem Browser (fast ausschließlich Uploads), aber diese Aufgaben werden jetzt von scp erledigt. Das einzige, was ich heute mit ftp verwende, ist das Hochladen von Inhalten auf einen minimalistischen Webhost. Natürlich YMMV. ^ _ ^
Robert Fisher
2
Genau diese Art von Antwort bringt mich dazu, diese Seite zu lieben. Wie gewähre ich ihm ein Kopfgeld?
Der Brasilianer
1
@ ruda.almeida von Ihnen nicht einverstanden sind, können Sie darüber auf meta.superuser.com posten, es wird diskutiert und vielleicht wird jemand die Frage erneut öffnen.
Gronostaj
54

Der HTTP- Content-LengthHeader ist in einigen Fällen optional und kann daher möglicherweise nicht mit der Datei übertragen werden. Das Ende der Datei wird signalisiert, wenn der Socket geschlossen wird.

Ignacio Vazquez-Abrams
quelle
1
Um genau zu sein, definierte HTTP 1.0 die Inhaltslänge, indem das Socket nach jedem Dokument geschlossen wurde. Dies wird aus Kompatibilitätsgründen in HTTP 1.1 weiterhin unterstützt. HTTP 1.1 ermöglicht jedoch die Wiederverwendung von Verbindungen für mehrere Dokumente, wenn entweder das Content-LengthHeaderfeld verwendet oder das Dokument mit übertragen wird Transfer-Encoding: chunked. Letzteres ermöglicht es, Inhalte dynamisch zu generieren und stückweise zu senden, wenn sie generiert werden, und das Ende des Dokuments zu signalisieren.
x4u
3

Wenn der Inhalt (z. B. ein .pdfDokument oder eine Excel-Tabelle) im Handumdrehen erstellt wird, kann die Größe vorher nicht bekannt sein. In diesem Fall kann der Server Ihnen die Größe des Downloads nicht vorher senden und der Browser kann die Gesamtgröße nicht anzeigen.

Uwe Plonus
quelle
9
@alfo muss anderer Meinung sein ... wenn ich Videos streame oder auch wenn ich Daten streame, die keine feste Größe haben, wenn es darum geht, die Daten so schnell wie möglich an den Benutzer weiterzuleiten. Ich werde die Größe an dem Punkt nicht wissen, an dem ich mit der Übertragung beginne
Foon,
4
@Alfo Sie können Daten wie .pdfDateien im laufenden Betrieb erstellen . Solange die Daten nicht vollständig geschrieben sind, kennen Sie die Größe nicht, aber Sie können den ata bereits an den Browser senden. Ich habe dies bereits in Java getan und eine Excel-Datei an den Browser gesendet, die im laufenden Betrieb generiert wurde. Von der Browserseite sah es wie ein Download aus, aber von der Serverseite ist es ein Streaming. So ist es möglich, Dateien zu streamen .pdf , auch wenn Sie sich das nicht vorstellen können. Aus dem Browser sieht es aus wie ein Download ohne bekannte Länge.
Uwe Plonus
8
@Alfo - Es muss erst fertig erstellt werden, bevor das letzte Paket an den Client gesendet wird.
GalacticCowboy
4
@Alfo Ich habe mich nie mit Video- Streaming beschäftigt , sondern mit Streaming im Allgemeinen, das auch das Streaming einer .pdfDatei oder einer Excel- Tabelle sein kann !
Uwe Plonus
2
@Alfo - Sie haben einen gültigen Punkt. Dynamische Dateien können zunächst vollständig im Speicher erstellt und dann über HTTP gesendet werden. Die Länge des Inhalts kann einfach berechnet werden. Wenn der Server jedoch viele große, dynamisch erstellte Dateien sendet, die in viele Pakete zerlegt werden, ist es sinnvoll, dass der Server die Chunks erst sendet, wenn sie berechnet wurden (anstatt jede große Datei im Speicher erstellen zu müssen und dann schicken Sie es). HTTP 1.1 hat die Chunked-Transfer-Codierung speziell für diesen Zweck entwickelt.
Dr. Jimbob