Tại sao một số tệp tải xuống không biết kích thước của riêng họ? [bản sao]


82

Câu hỏi này đã có câu trả lời ở đây:

Đôi khi, khi tải xuống tệp trong trình duyệt web, tiến trình tải xuống không "biết" tổng kích thước của tệp hoặc khoảng thời gian tải xuống - nó chỉ hiển thị tốc độ tải xuống, với tổng cộng là "Không xác định".

Tại sao trình duyệt không biết kích thước cuối cùng của một số tệp? Nơi nào nó có được thông tin này ở nơi đầu tiên?


13
Các tệp được tạo động không có kích thước, chúng xuất hiện dưới dạng luồng cho đến khi đạt được EOF.
Phòng thí nghiệm Fiasco

Câu trả lời:


114

Để yêu cầu tài liệu từ máy chủ web, trình duyệt sử dụng giao thức HTTP. Bạn có thể biết tên đó từ thanh địa chỉ của bạn (bây giờ có thể bị ẩn, nhưng khi bạn nhấp vào thanh địa chỉ, sao chép URL và dán nó vào một số trình soạn thảo văn bản, bạn sẽ thấy http://ngay từ đầu). HTTP là một giao thức dựa trên văn bản đơn giản. Nó hoạt động như thế này:

Đầu tiên, trình duyệt của bạn kết nối với máy chủ của trang web và gửi URL của tài liệu mà nó muốn tải xuống (các trang web cũng là tài liệu) và một số chi tiết về chính trình duyệt (Tác nhân người dùng, v.v.). Ví dụ: để tải trang chính trên trang SuperUser http://superuser.com/, trình duyệt của tôi sẽ gửi một yêu cầu giống như sau:

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

Dòng đầu tiên chỉ định tài liệu nào máy chủ sẽ trả về. Các dòng khác được gọi là tiêu đề; họ trông như thế này:

Header name: Header value

Những dòng này gửi thông tin bổ sung giúp máy chủ quyết định phải làm gì.

Nếu tất cả đều ổn, máy chủ sẽ phản hồi bằng cách gửi tài liệu được yêu cầu. Phản hồi bắt đầu bằng một thông báo trạng thái, theo sau là một số tiêu đề (có chi tiết về tài liệu) và cuối cùng, nếu tất cả đều ổn, nội dung của tài liệu. Đây là nội dung trả lời của máy chủ SuperUser cho yêu cầu của tôi như sau:

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>

Sau dòng cuối cùng, máy chủ của SuperUser đóng kết nối.

Dòng đầu tiên ( HTTP/1.1 200 OK) chứa mã phản hồi , trong trường hợp này là 200 OK. Điều đó có nghĩa là máy chủ đã quyết định nó có thể trả lại một tài liệu, theo yêu cầu và hứa rằng các nội dung tiếp theo sẽ là một tài liệu như vậy. Nếu đây không phải là trường hợp mã sẽ là một cái gì đó khác và nó sẽ cung cấp một số dấu hiệu về lý do máy chủ không trả lại tài liệu dưới dạng phản hồi: ví dụ: nếu không thể tìm thấy tài liệu được yêu cầu, thì nó phải trả lại 404 Not Foundvà nếu bạn không được phép truy cập nội dung được đề cập thì nên trả lại 403 Forbidden.

Sau dòng trạng thái đầu tiên này, các tiêu đề phản hồi theo sau; họ cung cấp thêm thông tin về nội dung được trả lại, chẳng hạn như nội dung của nó Content-type.

Tiếp theo là một dòng trống. Nó báo hiệu thực tế rằng không có thêm tiêu đề phản hồi sẽ theo sau. Tất cả mọi thứ qua dòng đó là nội dung của tài liệu mà nó yêu cầu. Vì vậy, trong ví dụ trên, <!DOCTYPE html>là dòng đầu tiên của trang chủ SuperUser (tài liệu HTML). Nếu tôi yêu cầu tải xuống một tài liệu, nó có thể là một số ký tự vô nghĩa, bởi vì hầu hết các định dạng tài liệu không thể đọc được mà không xử lý trước.

Trở lại tiêu đề. Điều thú vị nhất đối với chúng tôi là cái cuối cùng , Content-Length. Nó thông báo cho trình duyệt biết cần bao nhiêu byte dữ liệu sau dòng trống, vì vậy về cơ bản, đó là kích thước tài liệu được biểu thị bằng byte. Tiêu đề này không bắt buộc và có thể bị máy chủ bỏ qua. Đôi khi kích thước tài liệu không thể dự đoán được (ví dụ: khi tài liệu được tạo nhanh chóng), đôi khi các lập trình viên lười biếng không bao gồm nó (khá phổ biến trên các trang web tải xuống trình điều khiển), đôi khi các trang web được tạo bởi những người mới không biết của một tiêu đề như vậy.

Dù sao, bất kể lý do là gì, tiêu đề có thể bị thiếu. Trong trường hợp đó, trình duyệt không biết máy chủ sẽ gửi bao nhiêu dữ liệu và do đó hiển thị kích thước tài liệu là không xác định , chờ máy chủ đóng kết nối. Và đó là lý do cho kích thước tài liệu không xác định.


4
Một lưu ý rất, rất nhỏ: Trình duyệt hỗ trợ các giao thức khác với HTTP. Nhưng các giao thức khác ngày nay rất hiếm, và về cơ bản các khái niệm tương tự áp dụng cho các giao thức khác mặc dù các chi tiết khác nhau.
Robert Fisher

5
@RobertFisher FTP là một giao thức hiếm? : p
Thomas

5
@Thomas Đó là kinh nghiệm của tôi những ngày này. Đã vài năm kể từ khi tôi nhớ thấy một URL ftp trong trình duyệt của mình. Cách đây vài năm, tôi đã sử dụng trực tiếp ftp chứ không phải với trình duyệt, tại nơi làm việc (gần như hoàn toàn tải lên), nhưng những tác vụ đó được xử lý bởi scp bây giờ. Điều duy nhất tôi sử dụng ftp cho ngày hôm nay là tải nội dung lên máy chủ web tối giản. Tất nhiên, YMMV. ^ _ ^
Robert Fisher

2
Đây chính xác là loại câu trả lời khiến tôi yêu thích trang web này. Làm thế nào để tôi cấp cho nó một tiền thưởng?
chàng người Brazil đó

1
@ ruda.almeida của bạn không đồng ý với điều đó, bạn có thể đăng bài về nó trên meta.superuser.com, nó sẽ được thảo luận và có thể ai đó sẽ mở lại câu hỏi.
gronostaj

54

Content-LengthTiêu đề HTTP là tùy chọn trong một số trường hợp và do đó, nó có thể không được truyền cùng với tệp; phần cuối của tệp sẽ được báo hiệu khi ổ cắm được đóng lại.


1
Nói chính xác, HTTP 1.0 đã xác định độ dài nội dung bằng cách đóng ổ cắm sau mỗi tài liệu. Điều này vẫn được hỗ trợ trong HTTP 1.1 để tương thích. Nhưng HTTP 1.1 cho phép sử dụng lại các kết nối cho nhiều tài liệu nếu trường Content-Lengthtiêu đề được sử dụng hoặc tài liệu được chuyển cùng Transfer-Encoding: chunked. Cái sau cho phép tự động tạo nội dung và gửi nó từng phần khi nó được tạo và có thể báo hiệu sự kết thúc của tài liệu.
x4u

3

Khi nội dung (ví dụ: .pdftài liệu hoặc bảng tính Excel) được tạo khi đang di chuyển, kích thước không thể biết trước. Trong trường hợp này, máy chủ không thể gửi cho bạn kích thước tải xuống trước đó và trình duyệt không thể hiển thị tổng kích thước.


9
@alfo sẽ không đồng ý ... nếu tôi phát trực tuyến video hoặc ngay cả khi tôi truyền bất kỳ loại dữ liệu nào không phải là kích thước cố định, nếu mục đích là lấy dữ liệu cho người dùng càng nhanh càng tốt, Tôi sẽ không biết kích thước tại điểm bắt đầu truyền
Foon

4
@Alfo Bạn có thể tạo dữ liệu như .pdfcác tệp khi đang di chuyển. Miễn là dữ liệu không được ghi một cách cạnh tranh, bạn không biết kích thước nhưng bạn có thể gửi ata cho trình duyệt. Tôi đã thực hiện điều này bằng Java và đã gửi một tệp Excel tới trình duyệt được tạo khi đang di chuyển. Từ phía trình duyệt, nó trông giống như một bản tải xuống nhưng từ phía máy chủ thì nó là một luồng. Vì vậy, có thể truyền phát .pdf tệp ngay cả khi bạn không tưởng tượng điều này. Từ trình duyệt, nó trông giống như một bản tải xuống mà không biết chiều dài.
Uwe Plonus

8
@Alfo - nó chỉ cần được hoàn thành được tạo trước khi gói cuối cùng được gửi đến máy khách.
GalacticCowboy

4
@Alfo Tôi chưa bao giờ nói về việc hấp video nhưng về phát trực tuyến nói chung, cũng có thể truyền phát .pdftệp hoặc bảng Excel!
Uwe Plonus

2
@Alfo - Bạn có một điểm hợp lệ, các tệp động có thể được tạo hoàn toàn đầu tiên trong bộ nhớ và sau đó được gửi qua HTTP và dễ dàng tính toán độ dài nội dung. Tuy nhiên, nếu máy chủ đang gửi nhiều tệp lớn được tạo động sẽ được chia thành nhiều gói, thì máy chủ sẽ bắt đầu gửi các khối khi chúng được tính toán (so với việc phải tạo mọi tệp lớn trong bộ nhớ và sau đó gửi nó). HTTP 1.1 đặc biệt thiết kế mã hóa chuyển khối chunked cho mục đích này.
dr jimbob
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.