HTTP头中的If-None-Match: *是什么意思?

55

以下是 HTTP 1.1 头部字段的翻译:

If-None-Match: *

我理解使用强 ETag、弱 ETag,甚至一系列 ETag 的情况,但不理解在使用星号 (*) 时的用途。

编辑:最好能提供一些伪代码(PHP 代码也可以),展示如何/什么时候回答"If-None-Match: *"。

2个回答

44
答案是:这取决于具体情况。
假设我们已经收到了
If-None-Match: *
If-Modified-Since: <yesterday date>

今天已经修改了页面。

首先,我们看一下 * 告诉我们:"如果资源存在且满足条件 (2),则返回 304"。好的,资源存在,但是条件 (2) 规定:"仅当日期晚于当前日期时才返回 304"。因此,这个条件没有得到满足,页面将会完全传送。

如果我们没有收到 If-Modified-Since,响应将会是 304。

如果在请求时该资源不存在,我们将返回适当的代码(就像没有 If-None-Match 一样)。

只有在 GET 和 HEAD 请求的响应中才应该返回 304,并且所有与缓存相关的响应头都必须存在。对于所有其他类型的请求,您的服务器需要回答 412(前提条件失败)。

希望它能有所帮助 ;)


当您在If-None-Match中使用*时,只有在设置并匹配If-Modified-Since的情况下才能发出304响应。 - AlexV
2
要么这样,要么干脆不用 If-Modified-Since。所以有两种方式。 - St.Woland
2
我认为这个答案是不准确的。假设ETags在表示更改时会发生变化,那么在同一请求中同时指定If-None-MatchIf-Modified-Since请求头是没有意义的(因为与ETag关联的Last-Modified日期永远不会改变)。除了一种情况,同时指定两者是有意义的:当同时存在If-None-MatchIf-Modified-Since时,除非服务器不支持If-None-Match,否则将忽略If-Modified-Since - Steven Liekens

14
引用自RFC 2616 (HTTP 1.1)
如果给定了“*”,并且该资源存在任何当前实体,则服务器不得执行请求的方法,除非由于资源的修改日期与请求中提供的If-Modified-Since头字段不匹配而必须执行。
RFC继续指出,服务器应该对GET和HEAD请求以304(未修改)进行响应,并对所有其他请求类型以412(前提条件失败)进行响应。但是,这仅适用于服务器实际上具有所请求资源的某个版本。如果没有任何实体,则应处理该请求(可能使用404,因为您没有任何内容)。
要处理请求,请首先确定如果该标头不存在,服务器将执行的操作。如果该请求的结果不是2xx或304,则正常提供服务。但是,如果请求的结果将是2xx或304,则处理If-None-Modified情况。当它是星号时,立即返回304(除非被If-Modified-Since推翻)。如果它是一个或多个实体标记,则检查是否有任何标记与您计划作为响应提供的标记匹配。如果有任何匹配项,则返回304;如果没有匹配项,则按照通常方式提供服务。
在RFC的后面,还有更多内容:
"If-None-Match: *" 的意思是,如果由源服务器(或缓存,可能使用Vary机制,请参见第14.44节)选择的表示形式存在,则不得执行该方法,并且应在该表示形式不存在时执行。此功能旨在有助于防止PUT操作之间的竞争。

也就是说,星号允许客户端表示:“如果已经存在任何版本的该文件,请不要进行PUT操作。”

5
这句话的普通英语意思是什么?如果提供了星号,我是否只需正常提供页面(而不使用 304)?即使提供了 If-Modified-Since… - AlexV
为什么这个 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match 上说,当与 If-Modified-Since 一起使用时,If-None-Match 优先级更高(如果服务器支持)。这与您所说的相反。 - Mohamad Haidar
If-Modified-Since 当与 If-None-Match 结合使用时,除非服务器不支持 If-None-Match,否则将被忽略。 - Mohamad Haidar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接