同时利用etags和chunked编码?

Joh*_*hir 11 etag http-content-length http-status-code-304 if-none-match

更新的问题

我的应用程序如何利用etags,并引入流/分块编码引入任何复杂性?


原始问题

在进行HTTP流式传输时Transfer-Encoding: chunked,Content-Length无法发送,因为它通常是未知的.

据我所知,当浏览器利用etags时,他们需要知道Content-Length.如果提供了etag但不提供Content-Length,则浏览器将永远不会发送If-None-Match.

有没有解决的办法?

Nie*_* B. 9

什么是实体标签?

Etags是用于版本页面的http标头,如果页面未更改,则允许客户端重用以前缓存的页面副本.

基本思想是客户端转到页面并向具有该页面的服务器发送http请求.然后,服务器呈现页面并将响应返回给客户端以及包含某些值的etag.除了显示页面之外,客户端还将在其本地缓存中提供该页面的副本以及etag.客户端下次访问该页面时,客户端将向Web服务器发出请求,但在If-None-Match标头中包含etag .这种请求称为条件GET.客户说,"我想要这个页面,但是我已经有了这个etag值的页面缓存版本,所以如果你认为我的缓存版本是最新的,请告诉我,我只是展示我的缓存副本给用户".

etag值没有任何语义要求.它应该用于存储一个值,允许您确定客户端副本是否是最新的.

最简单的方法是计算响应的哈希值,如果哈希值与请求头中的etag值匹配,则客户端已经拥有相同的副本,您可以返回一个304 No content并在响应中返回一个空主体.这比再次返回整个页面要快得多.

优化

虽然计算哈希是一种确定缓存是否仍然良好的简单而安全的方法,但是存在更智能的技术可以减少Web服务器的负载.考虑一个在网上商店中显示产品的页面.您可以只使用产品的updated_at属性,而不是使用产品描述呈现页面,然后计算和比较哈希值.这意味着您在应用程序中执行的第一件事是检查etag并从数据库中获取产品以比较该updated_at属性.如果匹配,则认为产品的详细信息未更改,您可以完成请求处理而无需进一步操作,然后返回304 No content响应.

但是,您应该小心这种优化,因为页面上可能有其他内容可能会过时,而不会影响updated_at数据库中产品的属性.这可能是带有最新消息的侧边栏,或者更糟糕的是,页面的个性化部分,例如列出以前添加的产品的购物车.

分块编码

分块编码仅仅是一种在多个块中传输响应的技术,因此接收客户端可以在服务器仍在处理剩余的块时更快地开始呈现页面.它与缓存没有任何关系.但是,如果要将响应的散列值用作etag,那么显然不可能,因为在您知道计算散列所需的完整响应之前发送标头.