这个问题基于本文
响应头
HTTP/1.1 200 OK
Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
ETag: "10c24bc-4ab-457e1c1f"
Content-Length: 12195
请求标头
GET /i/yahoo.gif HTTP/1.1
Host: us.yimg.com
If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
If-None-Match: "10c24bc-4ab-457e1c1f"
HTTP/1.1 304 Not Modified
在这种情况下,浏览器会同时发送 If-None-Match 和 If-Modified-Since。我的问题是,在服务器端,在发送 304 之前,我是否需要同时匹配 etag 和 If-Modified-Since。
或者
我是否应该只查看 etag,如果 etag 匹配则发送 304。在这种情况下,我忽略了 If-Modified-Since 。
答案1
摘录自RFC 2616“超文本传输协议 - HTTP/1.1”
13.3.4 何时使用实体标签和上次修改日期的规则
...
HTTP/1.1 原始服务器在收到包含 Last-Modified 日期(例如,在 If-Modified-Since 或 If-Unmodified-Since 标头字段中)和一个或多个实体标签(例如,在 If-Match、If-None-Match 或 If-Range 标头字段中)作为缓存验证器的条件请求时,不得返回 304(未修改)的响应状态,除非这样做与请求中的所有条件标头字段一致。
答案2
您只需发送并反向检查您感兴趣的对。因此,如果您有 ETag,请发送 ETag 标头并检查 If-None-Match 标头。如果您有 Last-Modified 日期,请发送 Last-Modified 日期并检查 If-Modified-Since 标头。
答案3
如果您可以在生成内容之前获取 Last-Modified,并且从内容中生成 etag,则应在生成内容之前检查 Last-Modified,如果匹配则中止生成,以节省服务器资源,特别是图形操作,我有一个 PHP 脚本,大约需要 0.8 秒才能检索图像,这里我使用服务器缓存生成图像,如果它过期了,大约需要 1.6 秒,否则我返回它,但是,在 if-modified-since 日期大于或等于修改日期时,我甚至不会从我的服务器缓存中检索它,最后我使用内容的 md5 校验和作为 etag,我生成的 etag 与 If-None-Match 请求标头匹配,我不费心发送数据,以节省服务器带宽。
答案4
服务器可以使用其中任意一种。假设您提供了两者,那么理论上您可以在服务器上检查两者,当然浏览器也应该同时提供两者。
您不妨检查哪个检查速度更快。例如,如果这些是磁盘上的文件,则检查上次修改时间 (mtime) 将比对内容进行 MD5 运算更快。
但在其他系统中,MD5 可以作为元数据存储在某个地方,例如在数据库或 S3 中的标头中,在这种情况下,ETag 实际上可能同样快。
当然你也不是必需的做任何事情。也就是说,您可以选择忽略其中任何一个,只返回带有内容的正常 200 代码。因此,如果这些事情对您不方便,请不要担心。