ทำไมไฟล์ที่ดาวน์โหลดบางไฟล์ไม่ทราบขนาดของตัวเอง [ซ้ำ]


82

บางครั้งเมื่อดาวน์โหลดไฟล์ในเว็บเบราว์เซอร์ความคืบหน้าการดาวน์โหลดจะไม่ "รู้" ขนาดรวมของไฟล์หรือขนาดของไฟล์ที่ดาวน์โหลดไปไกลเท่าไหร่ - มันเพิ่งแสดงความเร็วในการดาวน์โหลดด้วย รวมเป็น "ไม่ทราบ"

เหตุใดเบราว์เซอร์จะไม่ทราบขนาดสุดท้ายของไฟล์บางไฟล์ มันได้รับข้อมูลนี้จากที่ใดในตอนแรก


13
ไฟล์ที่สร้างขึ้นแบบไดนามิกมีขนาดไม่ได้ไฟล์จะมาเป็นสตรีมจนกว่าจะถึง EOF
Fiasco Labs

คำตอบ:


114

ในการขอเอกสารจากเว็บเซิร์ฟเวอร์เบราว์เซอร์ใช้โปรโตคอล HTTP คุณอาจรู้ชื่อนั้นจากแถบที่อยู่ของคุณ (อาจถูกซ่อนไว้ในตอนนี้ แต่เมื่อคุณคลิกที่แถบที่อยู่ให้คัดลอก URL และวางในตัวแก้ไขข้อความบางตัวคุณจะเห็นhttp://ที่จุดเริ่มต้น) HTTP เป็นโปรโตคอลข้อความที่เรียบง่าย มันได้ผลเช่นนี้:

ขั้นแรกเบราว์เซอร์ของคุณเชื่อมต่อกับเซิร์ฟเวอร์ของเว็บไซต์และส่ง URL ของเอกสารที่ต้องการดาวน์โหลด (หน้าเว็บเป็นเอกสารด้วย) และรายละเอียดบางอย่างเกี่ยวกับตัวเบราว์เซอร์ ( User-Agentฯลฯ ) ตัวอย่างเช่นหากต้องการโหลดหน้าหลักในเว็บไซต์ SuperUser http://superuser.com/เบราว์เซอร์ของฉันจะส่งคำขอที่มีลักษณะดังนี้:

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

บรรทัดแรกระบุว่าเอกสารใดที่เซิร์ฟเวอร์ควรส่งคืน บรรทัดอื่น ๆ เรียกว่าส่วนหัว พวกเขามีลักษณะเช่นนี้:

Header name: Header value

บรรทัดเหล่านี้ส่งข้อมูลเพิ่มเติมที่ช่วยให้เซิร์ฟเวอร์ตัดสินใจว่าจะทำอย่างไร

หากทุกอย่างเรียบร้อยเซิร์ฟเวอร์จะตอบกลับด้วยการส่งเอกสารที่ร้องขอ การตอบสนองเริ่มต้นด้วยข้อความสถานะตามด้วยส่วนหัวบางส่วน (พร้อมรายละเอียดเกี่ยวกับเอกสาร) และในที่สุดหากเนื้อหาของเอกสารนั้นดี นี่คือความคิดเห็นของเซิร์ฟเวอร์ SuperUser สำหรับคำขอของฉัน:

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>

หลังจากบรรทัดสุดท้ายเซิร์ฟเวอร์ของ SuperUser ปิดการเชื่อมต่อ

บรรทัดแรก ( HTTP/1.1 200 OK) มีรหัสการตอบสนอง200 OKในกรณีนี้มันเป็น หมายความว่าเซิร์ฟเวอร์ตัดสินใจว่าสามารถส่งคืนเอกสารตามที่ร้องขอและสัญญาว่าเนื้อหาที่ตามมาจะเป็นเอกสารดังกล่าว หากไม่ใช่ในกรณีที่รหัสจะเป็นอย่างอื่นและจะให้การบ่งชี้บางส่วนของเหตุผลที่เซิร์ฟเวอร์ไม่เพียงแค่ส่งคืนเอกสารตามการตอบสนอง: ตัวอย่างเช่นถ้ามันไม่สามารถหาเอกสารที่ร้องขอก็ควรจะกลับและถ้าคุณไม่ได้รับอนุญาตในการเข้าถึงเนื้อหาในคำถามที่มันควรจะกลับมา404 Not Found403 Forbidden

หลังจากบรรทัดสถานะแรกนี้ส่วนหัวการตอบสนองจะตามมา Content-typeพวกเขาให้ข้อมูลเพิ่มเติมเกี่ยวกับเนื้อหาที่จะส่งกลับเช่นของมัน

ถัดไปเป็นบรรทัดว่าง มันส่งสัญญาณความจริงที่ว่าไม่มีส่วนหัวการตอบสนองอีก ทุกอย่างที่ผ่านมาบรรทัดนั้นคือเนื้อหาของเอกสารที่ร้องขอ ดังนั้นในตัวอย่างข้างต้น<!DOCTYPE html>คือบรรทัดแรกของหน้าแรก SuperUser (เอกสาร HTML) ถ้าฉันขอให้ดาวน์โหลดเอกสารมันอาจจะเป็นตัวอักษรที่พูดพล่อยๆเพราะรูปแบบเอกสารส่วนใหญ่ไม่สามารถอ่านได้โดยไม่ต้องดำเนินการก่อน

กลับไปที่ส่วนหัว Content-Lengthหนึ่งที่น่าสนใจที่สุดสำหรับเราคือคนสุดท้าย มันแจ้งให้เบราว์เซอร์ทราบจำนวนไบต์ของข้อมูลที่ควรคาดหวังหลังจากบรรทัดว่างดังนั้นโดยทั่วไปแล้วขนาดของเอกสารที่แสดงเป็นไบต์ ส่วนหัวนี้ไม่บังคับและอาจถูกละเว้นโดยเซิร์ฟเวอร์ บางครั้งขนาดของเอกสารไม่สามารถคาดการณ์ได้ (ตัวอย่างเช่นเมื่อเอกสารถูกสร้างขึ้นอย่างฉับพลัน) บางครั้งโปรแกรมเมอร์ที่ขี้เกียจไม่ได้รวมมัน (พบได้ทั่วไปในเว็บไซต์ดาวน์โหลดไดรเวอร์) บางครั้งเว็บไซต์ก็ถูกสร้างขึ้นโดยมือใหม่ที่ไม่รู้ ของส่วนหัวดังกล่าว

อย่างไรก็ตามไม่ว่าเหตุผลใดก็ตามส่วนหัวอาจหายไป ในกรณีนี้เบราว์เซอร์ไม่ทราบว่าเซิร์ฟเวอร์จะส่งข้อมูลไปเท่าใดและแสดงขนาดเอกสารไม่เป็นที่รู้จักรอให้เซิร์ฟเวอร์ปิดการเชื่อมต่อ และนี่คือเหตุผลสำหรับขนาดเอกสารที่ไม่รู้จัก


4
หมายเหตุที่น้อยมาก ๆ : เบราว์เซอร์รองรับโปรโตคอลอื่นที่ไม่ใช่ HTTP แต่โปรโตคอลอื่นหายากในปัจจุบันนี้และหลักการเดียวกันนี้ใช้กับโปรโตคอลอื่นแม้ว่ารายละเอียดจะแตกต่างกัน
Robert Fisher

5
@RobertFisher FTP เป็นโปรโตคอลหายากหรือไม่ : p
โทมัส

5
@Thomas นั่นคือประสบการณ์ของฉันในวันนี้ เป็นเวลาหลายปีแล้วที่ฉันจำการเห็น ftp URL ในเบราว์เซอร์ของฉัน ไม่กี่ปีที่ผ่านมาฉันใช้ ftp โดยตรงแทนที่จะใช้เบราว์เซอร์ที่ทำงาน (อัปโหลดเกือบทั้งหมด) แต่ตอนนี้ scp จัดการงานเหล่านั้นแล้ว สิ่งเดียวที่ฉันใช้ ftp สำหรับวันนี้คือการอัปโหลดเนื้อหาไปยังเว็บโฮสต์ที่เรียบง่าย แน่นอน YMMV ^ _ ^
Robert Fisher

2
ตรงนี้เป็นคำตอบที่ทำให้ฉันหลงรักเว็บไซต์นี้ ฉันจะให้ความโปรดปรานได้อย่างไร
Guy ชาวบราซิลนั่น

1
@ ruda.almeida ที่คุณไม่เห็นด้วยกับที่คุณสามารถโพสต์เกี่ยวกับมันใน meta.superuser.com มันจะมีการหารือและอาจมีคนจะเปิดคำถามอีกครั้ง
gronostaj

54

Content-Lengthส่วนหัวHTTP เป็นทางเลือกในบางกรณีและอาจไม่สามารถส่งไฟล์ดังกล่าวได้ จุดสิ้นสุดของไฟล์จะถูกส่งสัญญาณเมื่อซ็อกเก็ตถูกปิด


1
เพื่อความแม่นยำ HTTP 1.0 กำหนดความยาวเนื้อหาโดยปิดซ็อกเก็ตหลังเอกสารแต่ละฉบับ สิ่งนี้ยังคงได้รับการสนับสนุนใน HTTP 1.1 เพื่อความเข้ากันได้ แต่ HTTP 1.1 จะช่วยให้การใช้การเชื่อมต่อสำหรับเอกสารหลายถ้าทั้งข้อมูลส่วนหัวถูกนำมาใช้หรือเอกสารที่มีการโอนด้วยContent-Length Transfer-Encoding: chunkedหลังช่วยให้การสร้างเนื้อหาแบบไดนามิกและส่งเป็นชิ้น ๆ ตามที่ได้รับการสร้างและสามารถส่งสัญญาณในตอนท้ายของเอกสาร
x4u

3

เมื่อเนื้อหา (เช่น.pdfเอกสารหรือแผ่นงาน Excel) ถูกสร้างขึ้นอย่างรวดเร็วขนาดที่ไม่สามารถทราบมาก่อน ในกรณีนี้เซิร์ฟเวอร์ไม่สามารถส่งขนาดการดาวน์โหลดมาก่อนและเบราว์เซอร์ไม่สามารถแสดงขนาดรวมได้


9
@alfo จะต้องไม่เห็นด้วย ... หากฉันกำลังสตรีมวิดีโอหรือแม้ว่าฉันจะสตรีมข้อมูลประเภทใดก็ตามที่ไม่ใช่ขนาดคงที่หากประเด็นคือการรับข้อมูลให้กับผู้ใช้โดยเร็วที่สุด ฉันไม่รู้ขนาดที่จุดที่ฉันเริ่มการถ่ายทอด
Foon

4
@Alfo คุณสามารถสร้างข้อมูลเช่น.pdfไฟล์ได้ทันที ตราบใดที่ข้อมูลไม่ได้ถูกเขียนอย่างเชี่ยวชาญคุณก็ไม่รู้ขนาด แต่คุณสามารถส่ง ata ไปยังเบราว์เซอร์ได้ ฉันได้ทำมาแล้วใน Java และส่งไฟล์ Excel ไปยังเบราว์เซอร์ซึ่งสร้างขึ้นทันที จากด้านเบราว์เซอร์ดูเหมือนว่าจะดาวน์โหลด แต่จากฝั่งเซิร์ฟเวอร์มันคือการสตรีม ดังนั้นจึงเป็นไปได้ที่จะสตรีม .pdfไฟล์แม้ว่าคุณจะไม่นึกภาพนี้ จากเบราว์เซอร์ดูเหมือนว่าจะดาวน์โหลดโดยไม่ทราบระยะเวลา
Uwe Plonus

8
@Alfo - จะต้องสร้างให้เสร็จก่อนที่จะส่งแพ็คเก็ตสุดท้ายไปยังไคลเอ็นต์
GalacticCowboy

4
@Alfo ฉันไม่เคยพูดถึงเรื่องการทำวิดีโอเลยแต่เกี่ยวกับการสตรีมทั่วไปซึ่งสามารถสตรีม.pdfไฟล์หรือแผ่นงาน Excel ได้!
Uwe Plonus

2
@Alfo - คุณมีจุดที่ถูกต้องไฟล์แบบไดนามิกสามารถสร้างได้ทั้งหมดในหน่วยความจำก่อนจากนั้นส่งผ่าน HTTP และความยาวของเนื้อหาที่คำนวณได้ง่าย อย่างไรก็ตามหากเซิร์ฟเวอร์กำลังส่งไฟล์ที่สร้างขึ้นแบบไดนามิกขนาดใหญ่จำนวนมากซึ่งจะแบ่งออกเป็นแพ็กเก็ตจำนวนมากมันสมเหตุสมผลสำหรับเซิร์ฟเวอร์ที่จะเริ่มส่งชิ้นข้อมูลตามที่คำนวณได้ (เทียบกับการสร้างไฟล์ขนาดใหญ่ทุกไฟล์ในหน่วยความจำ) ส่ง). HTTP 1.1 ออกแบบมาเป็นพิเศษสำหรับการเข้ารหัสการถ่ายโอน chunkedสำหรับวัตถุประสงค์นี้
dr jimbob
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.