Mengapa beberapa file unduhan tidak tahu ukurannya sendiri? [duplikat]

82

Pertanyaan ini sudah ada jawabannya di sini:

Kadang-kadang, saat mengunduh file di browser web, progres pengunduhan tidak "tahu" ukuran total file, atau seberapa jauh dalam pengunduhannya - ini hanya menunjukkan kecepatan pengunduhannya, dengan total sebagai "Tidak Dikenal".

Mengapa peramban tidak mengetahui ukuran akhir beberapa file? Di mana ia mendapatkan informasi ini?

Coldblackice
sumber
13
File yang dibuat secara dinamis tidak memiliki ukuran, mereka datang sebagai aliran sampai EOF tercapai.
Fiasco Labs

Jawaban:

114

Untuk meminta dokumen dari server web, browser menggunakan protokol HTTP. Anda mungkin tahu nama itu dari bilah alamat Anda (mungkin disembunyikan sekarang, tetapi ketika Anda mengklik bilah alamat, salin URL dan tempel di beberapa editor teks, Anda akan melihat http://di awal). HTTP adalah protokol berbasis teks yang sederhana. Ini berfungsi seperti ini:

Pertama, browser Anda terhubung ke server situs web dan mengirimkan URL dokumen yang ingin diunduh (halaman web juga dokumen) dan beberapa detail tentang browser itu sendiri ( User-Agent dll). Misalnya, untuk memuat halaman utama di situs SuperUser http://superuser.com/,, browser saya mengirim permintaan yang terlihat seperti ini:

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

Baris pertama menentukan dokumen mana yang harus dikembalikan oleh server. Baris lain disebut header; mereka terlihat seperti ini:

Header name: Header value

Baris-baris ini mengirimkan informasi tambahan yang membantu server memutuskan apa yang harus dilakukan.

Jika semuanya baik-baik saja, server akan merespons dengan mengirimkan dokumen yang diminta. Respons dimulai dengan pesan status, diikuti oleh beberapa tajuk (dengan perincian tentang dokumen) dan akhirnya, jika semuanya baik-baik, konten dokumen. Seperti inilah balasan server SuperUser untuk permintaan saya:

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>

Setelah baris terakhir, server SuperUser menutup koneksi.

Baris pertama ( HTTP/1.1 200 OK) berisi kode respons , dalam hal ini 200 OK. Ini berarti bahwa server telah memutuskan dapat mengembalikan dokumen, seperti yang diminta, dan berjanji bahwa konten yang mengikuti akan menjadi dokumen seperti itu. Jika ini bukan masalahnya, kode akan menjadi sesuatu yang lain, dan itu akan memberikan beberapa indikasi alasan server tidak hanya mengembalikan dokumen sebagai tanggapan: misalnya, jika tidak dapat menemukan dokumen yang diminta, itu seharusnya mengembalikan 404 Not Found, dan jika Anda tidak diizinkan untuk mengakses konten yang dipermasalahkan itu seharusnya dikembalikan 403 Forbidden.

Setelah baris status pertama ini, header respons akan mengikuti; mereka memberikan lebih banyak informasi tentang konten yang dikembalikan, seperti itu Content-type.

Berikutnya adalah baris kosong. Ini menandakan fakta bahwa tidak ada lagi header respons yang akan mengikuti. Segala sesuatu yang melewati garis itu adalah isi dokumen yang diminta. Jadi pada contoh di atas, <!DOCTYPE html>adalah baris pertama halaman beranda SuperUser (dokumen HTML). Jika saya meminta dokumen untuk diunduh, mungkin ada beberapa karakter omong kosong, karena sebagian besar format dokumen tidak dapat dibaca tanpa pemrosesan sebelumnya.

Kembali ke tajuk. Yang paling menarik bagi kami adalah yang terakhir Content-Length,. Ini memberitahu browser berapa banyak byte data yang diharapkan setelah baris kosong, jadi pada dasarnya ukuran dokumen dinyatakan dalam byte. Header ini tidak wajib dan mungkin dihilangkan oleh server. Terkadang ukuran dokumen tidak dapat diprediksi (misalnya saat dokumen dihasilkan dengan cepat), terkadang programmer malas tidak memasukkannya (cukup umum di situs pengunduhan driver), terkadang situs web dibuat oleh pemula yang tidak tahu dari header seperti itu.

Pokoknya, apa pun alasannya, tajuknya bisa hilang. Dalam hal ini browser tidak tahu berapa banyak data yang akan dikirim oleh server, dan karenanya menampilkan ukuran dokumen sebagai tidak diketahui , menunggu server untuk menutup koneksi. Dan itulah alasan ukuran dokumen tidak diketahui.

gronostaj
sumber
4
Catatan yang sangat, sangat kecil: Browser mendukung protokol selain HTTP. Tetapi protokol lain jarang hari ini, dan pada dasarnya konsep yang sama berlaku untuk protokol lain meskipun detailnya berbeda.
Robert Fisher
5
@RobertFisher FTP adalah protokol yang langka? : p
Thomas
5
@ Thomas Itulah pengalaman saya hari ini. Sudah beberapa tahun sejak saya ingat melihat URL ftp di browser saya. Beberapa tahun yang lalu saya menggunakan ftp — langsung daripada dengan browser — di kantor (hampir seluruhnya mengunggah), tetapi tugas-tugas itu ditangani oleh scp sekarang. Satu-satunya hal yang saya gunakan ftp untuk hari ini adalah mengunggah konten ke host web minimalis. Tentu saja, YMMV. ^ _ ^
Robert Fisher
2
Ini adalah jawaban yang membuat saya menyukai situs ini. Bagaimana saya memberinya hadiah?
Orang Brasil itu,
1
@ ruda.almeida Anda tidak setuju dengan itu, Anda dapat mempostingnya di meta.superuser.com, itu akan dibahas dan mungkin seseorang akan membuka kembali pertanyaan.
gronostaj
54

Content-LengthHeader HTTP bersifat opsional dalam beberapa kasus, dan karena itu mungkin tidak dikirimkan bersama file; akhir file akan diberi sinyal ketika soket ditutup.

Ignacio Vazquez-Abrams
sumber
1
Lebih tepatnya, HTTP 1.0 mendefinisikan panjang konten dengan menutup soket setelah setiap dokumen. Ini masih didukung di HTTP 1.1 untuk kompatibilitas. Tetapi HTTP 1.1 memungkinkan untuk menggunakan kembali koneksi untuk banyak dokumen jika kolom Content-Lengthheader digunakan atau dokumen tersebut ditransfer Transfer-Encoding: chunked. Yang terakhir memungkinkan untuk secara dinamis menghasilkan konten dan mengirimkannya sedikit demi sedikit ketika dihasilkan dan dapat memberi sinyal pada akhir dokumen.
x4u
3

Ketika konten (misalnya .pdfdokumen atau lembar Excel) dibuat dengan cepat, ukurannya tidak dapat diketahui sebelumnya. Dalam hal ini server tidak dapat mengirimi Anda ukuran unduhan sebelumnya dan browser tidak dapat menampilkan ukuran total.

Uwe Plonus
sumber
9
@ Jika Anda harus tidak setuju ... jika saya streaming video, atau bahkan jika saya streaming segala jenis data yang bukan ukuran tetap, jika intinya adalah untuk mendapatkan data kepada pengguna secepat mungkin, Saya tidak akan tahu ukuran pada titik di mana saya memulai pengiriman
Foon
4
@Alfo Anda dapat membuat data seperti .pdffile dengan cepat. Selama data tidak ditulis secara kompeten, Anda tidak tahu ukurannya tetapi Anda sudah dapat mengirim ata ke browser. Saya sudah melakukan ini di Jawa dan mengirim file Excel ke browser yang dibuat dengan cepat. Dari sisi browser itu tampak seperti unduhan tetapi dari sisi server itu adalah streaming. Jadi dimungkinkan untuk melakukan streaming .pdf file bahkan jika Anda tidak dapat membayangkan ini. Dari peramban itu terlihat seperti unduhan tanpa panjang yang diketahui.
Uwe Plonus
8
@Alfo - hanya perlu selesai dibuat sebelum paket terakhir dikirim ke klien.
GalacticCowboy
4
@Alfo Saya tidak pernah membahas tentang pengukusan video selain tentang streaming secara umum, yang juga bisa streaming .pdffile atau lembar Excel!
Uwe Plonus
2
@Alfo - Anda memiliki titik valid, file dinamis dapat seluruhnya dibuat pertama dalam memori dan kemudian dikirim melalui HTTP dan mudah untuk menghitung panjang konten. Namun, jika server mengirim banyak file besar yang dibuat secara dinamis yang akan dipecah menjadi banyak paket, masuk akal bagi server untuk mulai mengirim potongan seperti yang dihitung (dibandingkan harus membuat setiap file besar dalam memori dan kemudian Kirimkan). HTTP 1.1 secara khusus merancang pengkodean transfer chunked untuk tujuan ini.
dr jimbob