如果在初始请求中获得资源,条件GET的条件是什么?

时间:2015-11-12 22:20:34

标签: get http-headers conditional restful-authentication http-1.1

分解条件GET的原因:

RFC 2616中,如果请求消息包含If-*If-Modified-SinceIf-Unmodified-Since,{{1},则表明GET方法更改为“条件GET” },If-MatchIf-None-Match)标题字段。

然后声明:

  

条件GET方法请求在条件标题字段描述的情况下 ONLY 传输实体。

根据我的理解,这表示如果在任何新的后续请求中遇到“If-Range条件,它将仅返回所请求的数据。例如,如果GET请求返回带有If-*标头的响应,则下一个请求必须包含Etag If-None-Match值,以便将客户端传回所请求的资源。

但是,如果客户端必须在获取返回的“ETag”标头之前发送初始请求(以ETag返回),则他们已经拥有所请求的资源。因此,任何返回带有If-None-Match值的If-None-Match标头的未来请求仅指示返回请求的值,返回 200 OK (如果客户端未返回{来自初始请求的{1}}和ETag值或 304 Not Modified (如果他们这样做),这可以通过缓存资源来帮助客户端和服务器。

我的问题:

为什么它声明实体(来自请求的资源)将“仅> ”<{1>}满足条件(如我的示例中客户端返回If-None-MatchETag以缓存所请求的资源)如果资源或“实体”正在返回是否返回“If-*”?在条件标头描述的情况下,它不会返回资源“ ”,因为它返回资源,尽管返回 200确定 304未修改,具体取决于是否返回“ETag”标头。我对此有何误解?

来自RFC 2616的完整条件GET参考:

  

如果请求消息包含If-Modified-Since,If-Unmodified-Since,If-Match,If-None-Match或If-Range标头字段,则GET方法的语义将更改为“条件GET” 。条件GET方法请求仅在条件头字段描述的情况下传送实体。条件GET方法旨在通过允许刷新缓存实体而不需要多个请求或传输客户端已经拥有的数据来减少不必要的网络使用。

1 个答案:

答案 0 :(得分:2)

首先,请注意RFC 2616已过时,您应该转而使用RFC 7232

很难看出究竟让您感到困惑的是什么。所以,让我用例子说明一下。

场景1

客户端A :我需要http://example.com/foo/bar

GET /foo/bar HTTP/1.1
Host: example.com

服务器:你走了。

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 12
ETag: "2ac07d4"

Hello world!

(一段时间过去了)

客户端A :我再次需要http://example.com/foo/bar。但我的缓存中已经有"2ac07d4"版本。也许那会吗?

GET /foo/bar HTTP/1.1
Host: example.com
If-None-Match: "2ac07d4"

服务器:是的,"2ac07d4"没问题。只需从你的缓存中取出它,我就不会发送给你。

HTTP/1.1 304 Not Modified

场景2

客户端A :我需要http://example.com/foo/bar

GET /foo/bar HTTP/1.1
Host: example.com

服务器:你走了。

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 12
ETag: "2ac07d4"

Hello world!

(一段时间过去了)

客户B :我想上传新版http://example.com/foo/bar

PUT /foo/bar HTTP/1.1
Content-Type: text/plain
Content-Length: 17

Hello dear world!

服务器:这看起来不错,我保存了它。我将此版本称为"f6049b9"

HTTP/1.1 204 No Content
ETag: "f6049b9"

(更多时间过去了)

客户端A :我再次需要http://example.com/foo/bar。但我的缓存中已经有"2ac07d4"版本。也许那会吗?

GET /foo/bar HTTP/1.1
Host: example.com
If-None-Match: "2ac07d4"

服务器:对不起,"2ac07d4"已过期。我们现在有一个新版本,它被称为"f6049b9"。在这里,让我发给你。

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 17
ETag: "f6049b9"

Hello dear world!

分析

  

条件GET方法请求在条件标题字段描述的情况下 ONLY 传输实体。

考虑客户A的第二个请求(在两种情况下)。

条件标题字段为:If-None-Match: "2ac07d4"

它描述的情况是:&#34;资源的选定表示与实体标记"2ac07d4"&#34;不匹配。

场景1:环境成立,因为所选资源的表示(包含Hello world!的表示)确实与实体标记"2ac07d4"匹配。因此,根据协议,服务器在其响应中传输实体。

场景2:情况执行保留:所选资源的表示(包含Hello dear world!的表示)与实体标记"2ac07d4"不匹配(它匹配"f6049b9"而不是)。因此,根据协议,服务器确实在其响应中传输实体。

无论如何,服务器如何提出这些"2ac07d4""f6049b9"?当然,这取决于应用程序,但是一种直接的方法是计算实体主体的哈希值(例如SHA-1) - 即使引入了小的更改,该值也会发生显着变化。