【问题标题】:How does a web server determine if an ETag value is current?Web 服务器如何确定 ETag 值是否是最新的?
【发布时间】:2019-11-03 18:59:37
【问题描述】:

示例场景

假设/some-view 有一个资源,它显示基于数据库查询的列表,例如

  • 项目 1
  • 项目 2
  • 项目 3

客户端 X 向/some-view 发出第一个请求,服务器处理响应,缓存它,生成一个 etag,然后用 200 发回。

现在已经过了一段时间,/some-view 的列表包含另一个项目

  • 项目 1
  • 项目 2
  • 项目 3
  • 项目 4

假设客户端 X 再次发送第一个请求,服务器是否会以 304 响应,直到另一个请求,例如客户端 Y,强制生成新的 etag 值,或者服务器是否实际处理响应并将其与当前 etag 进行比较以确定它是否仍然有效?也许不同的网络服务器处理方式不同?

【问题讨论】:

  • 如何生成 etags 完全取决于网络服务器/应用程序。从 HTTP RFC 和客户端的角度来看 - 它只是一个任意字符串。

标签: http server etag


【解决方案1】:

如果响应是动态生成的,服务器实际上必须生成它才能生成 ETag 并将其与请求进行比较。如果它们匹配,那么服务器可以避免发送响应,但它不能避免首先生成它,至少在 ETag 只是响应的哈希的一般情况下(例如,ETag 过滤器)不会.当然 ETag 可以是任何东西,因此对于一般情况下服务器必须生成响应,如果您制作自己的 ETag,您可以在其中包含一些信息,您的服务器可以使用这些信息来确定它是否可以只返回 304 而无需必须生成响应。

【讨论】:

    【解决方案2】:

    ETag 有两种场景:ETag 用于静态资源(文件),ETag 用于动态查询结果(如问题所述)。

    如果“web server”是指Apache或Nginx等服务器软件,它只提供静态资源的ETag功能,不会自动生成或更新动态结果的ETag。比如根据Nginxdocument

    语法:etag on |关闭;

    默认:etag 开启;

    静态资源启用或禁用“ETag”响应标头字段的自动生成。

    原因是:Web服务器软件可以监听文件变化并更新ETag,但永远无法判断Database中的一堆数据是否被修改。

    如果“网络服务器”是指服务器端逻辑,您可以自己生成和管理 ETag(例如 URL 与其对应的 ETag 的映射)。 RFC7232 的唯一要求是:

    源服务器应该为任何选定的表示发送一个 ETag 变化检测可以合理且一致 确定

    因此,这里的重点是“检测变化”——您可以选择最合适的解决方案:

    • 监听写入资源操作,并更新 ETag。
    • 在后台每 5 分钟查询一次资源,一旦有变化就更新 ETag。
    • 有问题描述的“客户端 Y”解决方案。
    • 有问题描述的“处理和比较”解决方案。
    • 更多...

    只要解决方案能够合理一致地检测到变化,就是一个很好的解决方案。

    【讨论】:

      猜你喜欢
      • 2018-07-06
      • 1970-01-01
      • 2019-01-29
      • 1970-01-01
      • 2020-03-30
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多