get - 如果资源是在初始请求中获取的,是什么让条件 GET 为 "conditional"?

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

分解条件 GET 的组成部分:

RFC 2616它声明如果请求消息包含 If-* (If-Modified-Since, If-Unmodified- SinceIf-MatchIf-None-MatchIf-Range) header 字段。

然后说:

A conditional GET method requests that the entity be transferred ONLY under the circumstances described by the conditional header field(s).

根据我的理解,这是说如果 condition 在任何新的后续请求中满足“If-*”,它只会返回请求的数据。例如,如果 GET 请求返回带有 Etag header 的响应,那么下一个请求必须包含带有 ETagIf-None-Match将客户端传回所请求资源的值。

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

我的问题:

如果如果- * 条件满足(就像在我的示例中,客户端返回带有 If-None-MatchETag 值以缓存请求的资源)如果返回资源或“实体”时是否返回“If-*”?它不会返回资源“在条件 header 描述的情况下”因为它返回资源尽管返回200 OK304 Not Modified 取决于是否返回“If-*” header 。我对此有什么误解?

来自 RFC 2616 的完整条件 GET 引用:

The semantics of the GET method change to a "conditional GET" if the request message includes an If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. A conditional GET method requests that the entity be transferred only under the circumstances described by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network usage by allowing cached entities to be refreshed without requiring multiple requests or transferring data already held by the client.

最佳答案

首先,请注意 RFC 2616 已过时,您应该引用 RFC 7232 .

很难看出到底是什么让您感到困惑。所以让我用例子来说明。

场景一

客户 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!

分析

A conditional GET method requests that the entity be transferred ONLY under the circumstances described by the conditional header field(s).

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

条件头字段是:If-None-Match: "2ac07d4"

它描述的情况是:“资源的选定表示不匹配实体标签“2ac07d4””。

场景 1:情况成立,因为所选的资源表示(包含 Hello world! 的表示)确实匹配实体标签 “2ac07d4”。因此,根据协议(protocol),服务器不会在其响应中传输实体。

场景 2:情况确实成立:资源的选定表示(包含 Hello dear world! 的表示)与实体标签 不匹配“2ac07d4”(它匹配 “f6049b9”)。因此,根据协议(protocol),服务器确实在其响应中传输实体。

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

关于get - 如果资源是在初始请求中获取的,是什么让条件 GET 为 "conditional"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33682533/

相关文章:

javascript - Base64 Alfresco 上的 GET 请求

magento - 如何从订单 ID Magento 获取所有订单详细信息,包括付款客户和运输详细信息

http-headers - 403 Forbidden 与 401 Unauthorized HTTP 响应

python - 如何在 Google App Engine for Python 上设置 ETAGS?

loops - 最小高度,最小宽度在不同图像方向上填充 div

json - 使用 httparty ruby​​gem 发出 api 请求时如何处理分页

http - 为什么本地主机上的 Julia 服务器挂起?

rest - 哪个 RESTful HTTP 动词用于读取时变状态?

javascript - 如何每 x 金额检查一个数字

javascript - JavaScript 中 Math.min 或 Math.max 内的条件语句