Perché alcuni file scaricati non conoscono le proprie dimensioni? [duplicare]


82

Questa domanda ha già una risposta qui:

Di tanto in tanto, quando si scarica un file in un browser Web, l'avanzamento del download non "conosce" la dimensione totale del file o quanto è lungo il download: mostra solo la velocità con cui viene scaricato, con un totale come "Sconosciuto".

Perché il browser non dovrebbe conoscere la dimensione finale di alcuni file? Da dove vengono queste informazioni in primo luogo?


13
I file creati dinamicamente non hanno dimensioni, vengono visualizzati come stream fino al raggiungimento di EOF.
Fiasco Labs

Risposte:


114

Per richiedere documenti dai server Web, i browser utilizzano il protocollo HTTP. Potresti conoscere quel nome dalla tua barra degli indirizzi (ora potrebbe essere nascosto, ma quando fai clic sulla barra degli indirizzi, copi l'URL e lo incolli in un editor di testo, vedrai http://all'inizio). HTTP è un semplice protocollo testuale. Funziona così:

Innanzitutto, il browser si connette al server del sito Web e invia un URL del documento che desidera scaricare (anche le pagine Web sono documenti) e alcuni dettagli sul browser stesso ( User-Agent ecc.). Ad esempio, per caricare la pagina principale sul sito SuperUser http://superuser.com/, il mio browser invia una richiesta simile alla seguente:

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

La prima riga specifica quale documento deve essere restituito dal server. Le altre linee sono chiamate header; sembrano così:

Header name: Header value

Queste righe inviano ulteriori informazioni che aiutano il server a decidere cosa fare.

Se tutto va bene, il server risponderà inviando il documento richiesto. La risposta inizia con un messaggio di stato, seguito da alcune intestazioni (con dettagli sul documento) e infine, se tutto va bene, il contenuto del documento. Ecco come appare la risposta del server SuperUser per la mia richiesta:

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>

Dopo l'ultima riga, il server di SuperUser chiude la connessione.

La prima riga ( HTTP/1.1 200 OK) contiene il codice di risposta , in questo caso è 200 OK. Significa che il server ha deciso di poter restituire un documento, come richiesto, e promette che il contenuto che segue sarà tale documento. In caso contrario, il codice sarà qualcos'altro e fornirà alcune indicazioni del motivo per cui il server non sta semplicemente restituendo un documento come risposta: ad esempio, se non riesce a trovare il documento richiesto, dovrebbe restituire 404 Not Founde se non ti è consentito accedere al contenuto in questione, dovrebbe tornare 403 Forbidden.

Dopo questa prima riga di stato, seguono le intestazioni di risposta; forniscono ulteriori informazioni sul contenuto restituito, come ad esempio il suo Content-type.

La prossima è una riga vuota. Segnala il fatto che non seguiranno più header di risposta. Tutto oltre quella linea è il contenuto del documento richiesto. Quindi nell'esempio sopra, <!DOCTYPE html>è la prima riga della home page di SuperUser (un documento HTML). Se avessi richiesto il download di un documento, probabilmente sarebbero stati alcuni caratteri incomprensibili, poiché la maggior parte dei formati di documento è illeggibile senza una precedente elaborazione.

Torna alle intestazioni. Il più interessante per noi è l'ultimo, Content-Length. Informa il browser di quanti byte di dati dovrebbe aspettarsi dopo la riga vuota, quindi sostanzialmente è la dimensione del documento espressa in byte. Questa intestazione non è obbligatoria e può essere omessa dal server. A volte le dimensioni del documento non possono essere previste (ad esempio quando il documento viene generato al volo), a volte i programmatori pigri non lo includono (abbastanza comune sui siti di download dei driver), a volte i siti Web sono creati da principianti che non sanno di tale intestazione.

Comunque, qualunque sia il motivo, l'intestazione può mancare. In tal caso il browser non sa quanti dati il ​​server invierà e quindi visualizza le dimensioni del documento come sconosciute , in attesa che il server chiuda la connessione. E questa è la ragione per dimensioni di documenti sconosciute.


4
Una nota molto, molto minore: i browser supportano protocolli diversi da HTTP. Ma altri protocolli sono rari in questi giorni, e sostanzialmente gli stessi concetti si applicano ad altri protocolli anche se i dettagli sono diversi.
Robert Fisher,

5
@RobertFisher FTP è un protocollo raro? : p
Thomas,

5
@Thomas Questa è la mia esperienza in questi giorni. Sono passati diversi anni da quando ricordo di aver visto un URL ftp nel mio browser. Qualche anno fa stavo usando ftp, direttamente anziché con un browser, al lavoro (caricamenti quasi interamente), ma quelle attività sono ora gestite da scp. L'unica cosa che uso ftp per oggi è il caricamento di contenuti su un host web minimalista. Certo, YMMV. ^ _ ^
Robert Fisher,

2
Questo è esattamente il tipo di risposta che mi fa amare questo sito. Come posso concedergli una taglia?
Quel ragazzo brasiliano, il

1
@ ruda.almeida non è d'accordo con te, puoi pubblicarlo su meta.superuser.com, verrà discusso e forse qualcuno riaprirà la domanda.
gronostaj,

54

L' Content-Lengthintestazione HTTP è facoltativa in alcuni casi e come tale potrebbe non essere trasmessa con il file; la fine del file verrà segnalata alla chiusura del socket.


1
Per essere precisi, HTTP 1.0 ha definito la lunghezza del contenuto chiudendo il socket dopo ogni documento. Questo è ancora supportato in HTTP 1.1 per compatibilità. HTTP 1.1 consente di riutilizzare le connessioni per più documenti se Content-Lengthviene utilizzato il campo di intestazione o il documento viene trasferito con Transfer-Encoding: chunked. Quest'ultimo consente di generare dinamicamente contenuto e inviarlo a tratti man mano che viene generato ed è in grado di segnalare la fine del documento.
x4u,

3

Quando il contenuto (ad es. Un .pdfdocumento o un foglio Excel) viene creato al volo, la dimensione non può essere conosciuta prima. In questo caso il server non può inviarti la dimensione del download prima e il browser non può visualizzare la dimensione totale.


9
@alfo non sarà d'accordo ... se sto trasmettendo video in streaming, o anche se sto trasmettendo qualsiasi tipo di dati che non è una dimensione fissa, se il punto è quello di ottenere i dati per l'utente il più rapidamente possibile, Non saprò le dimensioni nel punto in cui inizio la trasmissione
Foon,

4
@Alfo Puoi creare dati come .pdffile al volo. Finché i dati non sono scritti in modo competente non si conoscono le dimensioni ma è possibile inviare l'ATA già al browser. L'ho già fatto in Java e ho inviato un file Excel al browser che è stato generato al volo. Dal lato browser sembrava un download ma dal lato server è uno streaming. Quindi è possibile eseguire lo streaming di .pdf file anche se non lo si immagina. Dal browser sembra un download senza lunghezza nota.
Uwe Plonus,

8
@Alfo - deve solo essere completato per essere creato prima che l'ultimo pacchetto sia inviato al client.
GalacticCowboy,

4
@Alfo Non ho mai pensato al video steaming ma allo streaming in generale, che può anche essere lo streaming di un .pdffile o di un foglio Excel!
Uwe Plonus,

2
@Alfo - Hai un punto valido, i file dinamici potrebbero essere interamente creati prima in memoria e quindi inviati tramite HTTP e la sua lunghezza del contenuto è facile da calcolare. Tuttavia, se il server sta inviando molti file di grandi dimensioni creati dinamicamente che verranno suddivisi in molti pacchetti, è logico che il server inizi a inviare i blocchi man mano che vengono calcolati (anziché dover creare tutti i file di grandi dimensioni in memoria e quindi invialo). HTTP 1.1 ha progettato specificamente la codifica di trasferimento in blocchi per questo scopo.
dr jimbob,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.