Dlaczego niektóre pobierane pliki nie mają własnego rozmiaru? [duplikować]


82

To pytanie ma już odpowiedź tutaj:

Czasami podczas pobierania pliku w przeglądarce internetowej postęp pobierania nie „zna” całkowitego rozmiaru pliku ani tego, jak daleko jest w pobraniu - pokazuje tylko szybkość, z jaką jest pobierany, z ogółem jako „Nieznany”.

Dlaczego przeglądarka nie zna ostatecznego rozmiaru niektórych plików? Skąd ta informacja?


13
Pliki tworzone dynamicznie nie mają rozmiaru, przechodzą jako strumień, aż do osiągnięcia EOF.
— Fiasco Labs

Odpowiedzi:


114

Do żądania dokumentów z serwerów WWW przeglądarki używają protokołu HTTP. Możesz znać tę nazwę z paska adresu (może być teraz ukryty, ale kiedy klikniesz pasek adresu, skopiuj adres URL i wklej go w edytorze tekstów, zobaczysz http://na początku). HTTP to prosty protokół tekstowy. Działa to tak:

Po pierwsze, przeglądarka łączy się z serwerem witryny i wysyła adres URL dokumentu, który chce pobrać (strony internetowe też są dokumentami) oraz niektóre szczegóły dotyczące samej przeglądarki ( User-Agent itp.). Na przykład, aby załadować stronę główną na stronie SuperUser http://superuser.com/, moja przeglądarka wysyła żądanie, które wygląda następująco:

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

Pierwszy wiersz określa, który dokument powinien zwrócić serwer. Pozostałe linie nazywane są nagłówkami; wyglądają tak:

Header name: Header value

Linie te wysyłają dodatkowe informacje, które pomagają serwerowi zdecydować, co robić.

Jeśli wszystko będzie w porządku, serwer odpowie, wysyłając żądany dokument. Odpowiedź zaczyna się od komunikatu o stanie, po którym następuje kilka nagłówków (ze szczegółami na temat dokumentu) i na koniec, jeśli wszystko jest w porządku, treść dokumentu. Tak wygląda odpowiedź serwera SuperUser na moje żądanie:

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>

Po ostatniej linii serwer SuperUser zamyka połączenie.

Pierwszy wiersz ( HTTP/1.1 200 OK) zawiera kod odpowiedzi , w tym przypadku jest to 200 OK. Oznacza to, że serwer zdecydował, że może zwrócić dokument zgodnie z żądaniem, i obiecuje, że następująca zawartość będzie takim dokumentem. Jeśli tak nie jest, kod będzie czymś innym i dostarczy pewnej wskazówki, dlaczego serwer nie tylko zwraca dokument jako odpowiedź: na przykład, jeśli nie może znaleźć żądanego dokumentu, powinien zwrócić 404 Not Found, a jeśli nie masz dostępu do danej treści, powinna ona powrócić 403 Forbidden.

Po tej pierwszej linii statusu następują nagłówki odpowiedzi; dostarczają więcej informacji na temat zwracanej treści, na przykład jej Content-type.

Dalej jest pusta linia. Sygnalizuje to, że nie będzie już żadnych nagłówków odpowiedzi. Wszystko poza tym wierszem stanowi treść żądanego dokumentu. Tak więc w powyższym przykładzie <!DOCTYPE html>jest pierwszy wiersz strony głównej SuperUser (dokument HTML). Gdybym prosił o dokument do pobrania, prawdopodobnie byłyby to bełkotliwe znaki, ponieważ większość formatów dokumentów jest nieczytelna bez wcześniejszego przetworzenia.

Powrót do nagłówków. Najbardziej interesująca jest dla nas ostatni, Content-Length. Informuje przeglądarkę, ile bajtów danych powinno oczekiwać po pustym wierszu, więc w zasadzie jest to rozmiar dokumentu wyrażony w bajtach. Ten nagłówek nie jest obowiązkowy i może zostać pominięty przez serwer. Czasami nie można przewidzieć rozmiaru dokumentu (na przykład, gdy dokument jest generowany w locie), czasami leniwi programiści go nie uwzględniają (dość powszechne w witrynach pobierania sterowników), czasami strony internetowe są tworzone przez początkujących, którzy nie wiedzą takiego nagłówka.

W każdym razie, bez względu na przyczynę, może brakować nagłówka. W takim przypadku przeglądarka nie wie, ile danych ma wysłać serwer, a zatem wyświetla rozmiar dokumentu jako nieznany , czekając na zakończenie połączenia przez serwer. I to jest powód nieznanych rozmiarów dokumentów.


4
Bardzo, bardzo niewielka uwaga: przeglądarki obsługują protokoły inne niż HTTP. Ale inne protokoły są obecnie rzadkie i zasadniczo te same pojęcia dotyczą innych protokołów, chociaż szczegóły są różne.
— Robert Fisher

5
@RobertFisher FTP to rzadki protokół? : p
— Thomas

5
@Thomas Takie jest moje doświadczenie w tych dniach. Minęło kilka lat, odkąd pamiętam URL ftp w mojej przeglądarce. Kilka lat temu korzystałem z ftp - bezpośrednio zamiast z przeglądarki - w pracy (prawie w całości przesyłane), ale te zadania są teraz obsługiwane przez scp. Jedyną rzeczą, której używam dzisiaj ftp, jest przesyłanie treści do minimalistycznego hosta internetowego. Oczywiście, YMMV. ^ _ ^
— Robert Fisher,

2
To jest dokładnie taka odpowiedź, która sprawia, że ​​uwielbiam tę stronę. Jak przyznać nagrodę?
— Ten Brazylijczyk

1
@ ruda.almeida nie zgadzasz się z tym, możesz napisać o tym na meta.superuser.com, zostanie to omówione i być może ktoś otworzy pytanie ponownie.
— gronostaj

54

Content-LengthNagłówek HTTP jest w niektórych przypadkach opcjonalny i jako taki może nie zostać przesłany z plikiem; koniec pliku zostanie zasygnalizowany, gdy gniazdo zostanie zamknięte.


1
Mówiąc ściślej, HTTP 1.0 zdefiniował długość treści, zamykając gniazdo po każdym dokumencie. Jest to nadal obsługiwane w HTTP 1.1 dla kompatybilności. Ale HTTP 1.1 pozwala na ponowne wykorzystanie połączeń dla wielu dokumentów, jeśli Content-Lengthużywane jest pole nagłówka lub dokument jest przesyłany Transfer-Encoding: chunked. Ten ostatni umożliwia dynamiczne generowanie treści i wysyłanie jej fragmentarycznie w miarę generowania i jest w stanie zasygnalizować koniec dokumentu.
— x4u

3

Gdy treść (np. .pdfDokument lub arkusz Excela) jest tworzona w locie, nie można wcześniej określić rozmiaru. W takich przypadkach serwer nie może wcześniej wysłać rozmiaru pobierania, a przeglądarka nie może wyświetlić całkowitego rozmiaru.


9
@alfo będzie musiał się nie zgodzić ... jeśli przesyłam strumieniowo wideo, a nawet jeśli przesyłam strumieniowo jakiekolwiek dane, które nie mają ustalonego rozmiaru, jeśli chodzi o to, aby jak najszybciej przekazać dane użytkownikowi, Nie będę znać rozmiaru w punkcie, w którym rozpocznę przekaz
— Foon

4
@ Alfo Możesz tworzyć dane takie jak .pdfpliki w locie. Dopóki dane nie są poprawnie zapisane, nie znasz rozmiaru, ale możesz wysłać ata już do przeglądarki. Zrobiłem to już w Javie i wysłałem plik Excela do przeglądarki, który został wygenerowany w locie. Od strony przeglądarki wyglądało to na pobieranie, ale od strony serwerów jest to streaming. Możliwe jest więc przesyłanie strumieniowe .pdf plików, nawet jeśli sobie tego nie wyobrażasz. Z przeglądarki wygląda jak pobieranie bez znanej długości.
— Uwe Plonus,

8
@ Alfo - należy go tylko utworzyć, zanim ostatni pakiet zostanie wysłany do klienta.
— GalacticCowboy

4
@Alfo Nigdy nie brałem pod uwagę przesyłania strumieniowego wideo, ale ogólnie przesyłania strumieniowego , które może również przesyłać strumieniowo .pdfplik lub arkusz Excela!
— Uwe Plonus

2
@ Alfo - Masz prawidłowy punkt, pliki dynamiczne można najpierw całkowicie utworzyć w pamięci, a następnie przesłać przez HTTP i łatwo obliczyć długość treści. Jeśli jednak serwer wysyła wiele dużych dynamicznie tworzonych plików, które zostaną podzielone na wiele pakietów, sensowne jest, aby serwer po prostu zaczął wysyłać fragmenty zgodnie z ich obliczeniami (w przeciwieństwie do konieczności tworzenia każdego dużego pliku w pamięci, a następnie Wyślij to). W tym celu HTTP 1.1 specjalnie zaprojektował szyfrowanie transferu porcji .
— dr jimbob
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.