Web 服务器/http 协议如何处理版本控制和压缩?

Sun*_*sen 6 http compression web-server version-control gzip

当客户端浏览器从 Web 服务器请求文件时,我知道会执行某种检查,因为 Web 浏览器可能已经缓存了为网页提供服务所需的文件。因此,如果缓存中存在文件,则不会发送任何文件。但是如果服务器上的文件自从文件被缓存在浏览器中后发生了变化,无论如何都会发送和更新文件。

然后,如果您在服务器上启用了 gzip 之类的压缩,则必须在途中对要提供给客户端的文件进行 gzip,这需要一些服务器端处理。

但这是如何管理的?在我看来,逻辑方法是,Web 服务器也应该有一个缓存,其中包含在特定时间跨度内请求的所有文件的最新版本,因此是这些文件的压缩版本,这样压缩就不必了每次请求文件时执行。

而且,最终如何请求文件?浏览器是每次在 HTML 代码中遇到一个文件并且特定文件未存储在本地缓存中时询问文件,还是将所有需要的文件加起来并同时询问整个文件?

但这只是从编程的角度猜测,我真的不知道。

如果 Web 服务器系统之间的答案非常不同,那么我主要对 Apache 感兴趣,但也欢迎其他答案。

Dav*_*d Z 11

您可以在HTTP 规范 中详细了解它,但这里有一个要点:当浏览器需要请求文件时,它首先检查其本地缓存。主要有以下三种可能:

  1. 浏览器具有文件的本地(缓存)版本,该版本被标记为在某个时间到期,并且该时间是在未来。在这种情况下,浏览器可以选择按原样使用缓存版本,或者可以向服务器发送请求以查看文件是否已更改。如果浏览器发送请求,它将包含一个If-Modified-Since标头,其中包含上次访问文件的时间。
  2. 浏览器具有已过期文件的缓存版本。在这种情况下,浏览器肯定会向服务器发送请求以查看是否有新版本,并且该请求(通常)将包含一个If-Modified-Since包含上次访问文件时间的标头。
  3. 浏览器根本没有缓存文件,在这种情况下,它会发送一个没有If-Modified-Since标头的请求。

当请求到达服务器时,基本上会发生几件事情。如果请求中包括If-Modified-Since头,服务器将继续和使用HTTP 200(OK)响应代码发送回该文件。(或者它会发送一个 404 File Not Found, or 403 Forbidden, 或者任何合适的)但是如果请求确实包含了一个If-Modified-Since头,服务器知道它只有在文件自包含的时间以来被修改时才需要发回文件在标题中。现在,如果文件从那时起被修改,那么服务器将再次发回带有 200 或 403、404 代码的文件。但是如果文件没有自指定时间以来被修改 - 请记住,这意味着浏览器的缓存版本仍然是最新的 - 服务器可以用 304(未修改)代码响应,并忽略文件本身的内容。这节省了一定数量的网络流量。

现在,假设服务器将使用文件的完整内容进行响应,有几种方法可以解决这个问题,具体取决于服务器的编写和/或配置方式。显然,它可以在每次请求进来时从磁盘读取文件(或者运行程序来生成它,如果它是一个动态页面)然后将它发送回来,但正如你所知,这有点低效。服务器可以做的一件事是发回文件的 gzip 版本,如果浏览器指定Accept-Encoding: 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: close标题的图像 3
  • 服务器发送图像 3
  • 服务器关闭连接

Connection: close报头可以由任何一方被发送到指定的TCP / IP连接应关闭该请求已经完成之后。

希望这基本上能满足您的要求,但 HTTP 规范是一个巨大的文档,我忽略了很多微妙之处。我实际上觉得它读起来很有趣,所以我建议你去看看它(再说一次,我可能有点奇怪)。