然后,如果您在服务器上启用了像压缩一样的压缩,则必须在途中对要提供给客户端的文件进行gzip压缩,这需要进行一些服务器端处理.
但这是如何管理的?在我看来,逻辑方法是Web服务器也应该有一个缓存,包含在特定时间跨度内请求的所有文件的最新版本,因此是这些文件的压缩版本,因此压缩不必每次请求文件时都要完成.
而且,最终如何请求文件?浏览器是否要求文件,每次遇到HTML代码中的文件并且特定文件没有存储在本地缓存中,或者它是否需要将所有需要的文件相加并同时请求整个文件?
但这只是从编程的角度来猜测,我真的不知道.
如果Web服务器系统的答案非常不同,我主要对Apache感兴趣,但其他答案也很受欢迎.
解决方法
>浏览器具有文件的本地(缓存)版本,该版本标记为在特定时间到期,并且该时间在将来.在这种情况下,浏览器可以选择使用缓存版本,也可以向服务器发送请求以查看文件是否已更改.如果浏览器发送请求,它将包含一个If-Modified-Since标头,其中包含上次访问文件的时间.
>浏览器具有已过期的文件的缓存版本.在这种情况下,浏览器肯定会向服务器发送一个请求以查看是否有新版本,并且该请求将(通常)包含一个If-Modified-Since标头,其中包含上次访问该文件的时间.
>浏览器根本没有缓存文件,在这种情况下,它会发送一个没有If-Modified-Since标头的请求.
当请求到达服务器时,基本上会发生一些事情.如果请求不包含If-Modified-Since标头,则服务器将继续使用HTTP 200(OK)响应代码发回文件. (或者它将发送404文件未找到,或403禁止,或任何适当的)但如果请求确实包含If-Modified-Since标头,服务器知道它只需要发回文件,如果它是自标题中包含的时间开始修改.现在,如果文件从那时起被修改,那么服务器将再次发回代码为200或403,404的文件.但是,如果文件自指定时间以来未被修改 – 记住,这意味着浏览器的缓存版本仍然是最新的 – 服务器可以使用304(未修改)代码进行响应,并省略文件本身的内容.这节省了一些网络流量.
现在,假设服务器将使用文件的完整内容进行响应,有几种方法可以解决,具体取决于服务器的编写和/或配置方式.显然,它可以只是从磁盘读取文件(或运行程序来生成它,如果它是一个动态页面),每次请求进入并发送回来,但是如你所知,这是低效的.如果浏览器在其请求中指定了Accept-Encoding:gzip,则服务器可以做的一件事是发送回文件的gzip压缩版本.服务器保留gzip压缩文件的缓存版本确实有意义,并且Apache(可能还有大多数其他服务器)可以配置为这样做.当服务器准备发回gzip压缩响应时,它会根据原始文件的修改时间检查gzip压缩版本的修改时间,如果原始文件已更新,它将再次运行gzip并替换旧版本在缓存中使用新版本.
有时,如果频繁请求,服务器也可以将文件缓存在RAM中.我认为Apache可以配置为这样做,但我不确定. (正如您现在可能已经猜到的那样,使用Apache,所有这些都与配置有关.)
关于如何请求文件的问题,浏览器确实一次要求一个文件.每个HTML页面,CSS文件,Javascript文件,图像文件等对应于一个单独的HTTP请求.如果您感兴趣,像Wireshark这样的工具实际上可以向您显示进出您计算机的各个HTTP请求和响应.但是为了节省资源,TCP / IP连接通常通过一整套请求保持打开状态.例如,如果您有一个包含3个图像和CSS样式表的网页,您可能会得到如下序列:
>浏览器打开连接
>服务器确认连接
>浏览器请求HTML页面
>服务器发送HTML页面
>浏览器请求CSS样式表
>服务器发送CSS样式表
>浏览器请求图像1
>服务器发送图像1
>浏览器请求图像2
>服务器发送图像2
>浏览器使用Connection请求图像3:关闭标题
>服务器发送图像3
>服务器关闭连接
可以由任何一方发送Connection:close标头,以指定在该请求完成后应关闭TCP / IP连接.
希望这主要得到你所要求的,但HTTP规范是一个巨大的文件,我忽略了很多细微之处.我实际上发现这是一个中等有趣的阅读,所以我建议你去看看它(然后再说,我可能有点奇怪).