为什么有些下载文件不知道自己的大小?

Col*_*ice 88 browser download

有时,在 Web 浏览器中下载文件时,下载进度不“知道”文件的总大小,或下载的进度——它只显示下载速度,带有总计为“未知”。

为什么浏览器不知道某些文件的最终大小?它首先从哪里获得这些信息?

gro*_*taj 119

要从 Web 服务器请求文档,浏览器使用 HTTP 协议。您可能从地址栏中知道该名称(它现在可能已隐藏,但是当您单击地址栏、复制 URL 并将其粘贴到某个文本编辑器中时,您会http://在开头看到)。HTTP 是一种简单的基于文本的协议。它是这样工作的:

首先,您的浏览器连接到网站的服务器并发送它要下载的文档的 URL(网页也是文档)以及有关浏览器本身的一些详细信息(用户代理等)。例如,要加载 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
Run Code Online (Sandbox Code Playgroud)

第一行指定服务器应该返回哪个文档。其他行称为标题;它们看起来像这样:

Header name: Header value
Run Code Online (Sandbox Code Playgroud)

这些行发送帮助服务器决定做什么的附加信息。

如果一切顺利,服务器将通过发送请求的文档来响应。响应以状态消息开始,然后是一些标题(包含有关文档的详细信息),最后是文档内容(如果一切正常)。这是 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>
Run Code Online (Sandbox Code Playgroud)

在最后一行之后,SuperUser 的服务器关闭连接。

第一行 ( HTTP/1.1 200 OK) 包含响应代码,在本例中为200 OK. 这意味着服务器已经决定它可以根据请求返回一个文档,并承诺后面的内容将是这样的文档。如果不是这种情况,代码将是别的东西,并且它将提供一些指示服务器不只是返回文档作为响应的原因:例如,如果它找不到请求的文档,它应该返回404 Not Found,如果您不被允许访问有问题的内容,它应该返回403 Forbidden

在第一个状态行之后,是响应头;它们提供有关返回内容的更多信息,例如其Content-type.

接下来是一个空行。它表明不会有更多响应标头跟随的事实。该行之后的所有内容都是它请求的文档的内容。所以在上面的例子中,<!DOCTYPE html>是 SuperUser 主页(一个 HTML 文档)的第一行。如果我请求下载文档,它可能会是一些乱码,因为大多数文档格式在没有事先处理的情况下是不可读的。

回到标题。对我们来说最有趣的是最后一个,Content-Length。它通知浏览器在空行之后它应该期望多少字节的数据,所以基本上它是用字节表示的文档大小。此标头不是强制性的,服务器可能会省略该标头。有时无法预测文档大小(例如,当文档是动态生成时),有时懒惰的程序员不包括它(在驱动程序下载站点上很常见),有时网站是由不知道的新手创建的这样的标题。

无论如何,无论是什么原因,标题都可能丢失。在这种情况下,浏览器不知道服务器要发送多少数据,因此将文档大小显示为unknown,等待服务器关闭连接。这就是文档大小未知的原因。

  • @RobertFisher FTP 是一种罕见的协议吗?:p (6认同)
  • 一个非常非常小的注意事项:浏览器支持 HTTP 以外的协议。但是现在其他协议很少见,即使细节不同,基本上相同的概念也适用于其他协议。 (5认同)
  • @Thomas 这就是我这些天的经历。自从我记得在我的浏览器中看到一个 ftp URL 已经有好几年了。几年前,我在工作中直接使用 ftp,而不是通过浏览器(几乎完全上传),但这些任务现在由 scp 处理。我今天使用 ftp 的唯一目的是将内容上传到极简主义的网络主机。当然,YMMV。^_^ (5认同)
  • 这正是让我喜欢这个网站的那种答案。我如何授予它赏金? (3认同)

Ign*_*ams 55

Content-Length在某些情况下,HTTP标头是可选的,因此它可能不会与文件一起传输;当套接字关闭时,将发出文件结束的信号。

  • 准确地说,HTTP 1.0 通过在每个文档之后关闭套接字来定义内容长度。为了兼容性,这在 HTTP 1.1 中仍然受支持。但是,如果使用 `Content-Length` 标头字段或使用 `Transfer-Encoding: chunked` 传输文档,则 HTTP 1.1 允许为多个文档重用连接。后者允许动态生成内容并在生成时分段发送,并且能够发出文档结束的信号。 (2认同)