这个问题已经在这里有了答案:
- 浏览器如何知道已加载多少页面? 2个答案
有时,在网络浏览器中下载文件时,下载进度不会“知道”文件的总大小,也不知道下载的过程;它只是显示文件的下载速度,总计为“未知”。
浏览器为什么不知道某些文件的最终大小?它首先从何处获得此信息?
这个问题已经在这里有了答案:
有时,在网络浏览器中下载文件时,下载进度不会“知道”文件的总大小,也不知道下载的过程;它只是显示文件的下载速度,总计为“未知”。
浏览器为什么不知道某些文件的最终大小?它首先从何处获得此信息?
Answers:
要从Web服务器请求文档,浏览器使用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
这些行发送其他信息,以帮助服务器确定要做什么。
如果一切正常,服务器将通过发送请求的文档进行响应。响应从状态消息开始,然后是一些标题(包含有关文档的详细信息),最后,如果一切正常,则返回文档的内容。这是超级用户服务器对我的请求的答复如下:
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 Found
,并且如果不允许您访问有问题的内容,它应该返回403 Forbidden
。
在第一条状态行之后,是响应头。他们提供有关返回内容的更多信息,例如Content-type
。
接下来是一个空行。它表明以下事实:不再有响应头。该行之后的所有内容都是其请求的文档的内容。因此,在上面的示例中,<!DOCTYPE html>
是SuperUser主页(HTML文档)的第一行。如果我要下载文档,可能是一些乱码,因为大多数文档格式未经事先处理就无法读取。
返回标题。对我们来说最有趣的是最后一个Content-Length
。它通知浏览器在空行之后应该有多少字节的数据,因此基本上是用字节表示的文档大小。此标头不是必需的,服务器可以省略。有时无法预测文档的大小(例如,动态生成文档时),有时懒惰的程序员不包含它(在驱动程序下载站点上很常见),有时网站由不知道的新手创建这样的标题。
无论如何,无论原因是什么,标题都可能丢失。在那种情况下,浏览器不知道服务器将要发送多少数据,因此将文档大小显示为unknown,等待服务器关闭连接。这就是文档大小未知的原因。
HTTP Content-Length
标头在某些情况下是可选的,因此它可能不会与文件一起发送;当套接字关闭时,将指示文件的末尾。
Content-Length
标头字段或使用传输了文档,则HTTP 1.1允许为多个文档重用连接Transfer-Encoding: chunked
。后者允许动态生成内容,并在生成内容时分段发送它,并能够用信号通知文档的结尾。
快速创建内容(例如.pdf
文档或Excel工作表)时,大小是无法得知的。在这种情况下,服务器无法向您发送下载大小,并且浏览器也无法显示总大小。
.pdf
文件之类的数据。只要数据没有竞争性地写入,您就不知道大小,但是您可以将ata已经发送到浏览器。我已经用Java完成了此操作,并向浏览器发送了动态生成的Excel文件。从浏览器的角度看,它看起来像是下载,但从服务器的角度看,它是流媒体。因此,即使您无法想象,也可以流式传输 .pdf
文件。在浏览器中,它看起来像是没有已知长度的下载。
.pdf
文件或Excel工作表!