What does the HTTP header If-None-Match: * mean?

2020-05-14 00:05发布

问题:

What does the following HTTP 1.1 header mean?

If-None-Match: *

I understand it when using a strong or weak ETag or even a list of ETags, but I don't understant it's use when using star (*).

Edit: Would be nice to have some pseudocode (PHP code good also) that would show how/what to answer to "If-None-Match: *".

回答1:

The answer is: it depends.

Suppose we have received

If-None-Match: *
If-Modified-Since: <yesterday date>

And the page has been altered today.

First, we take a look at the * which tells us: "Return 304 if the resource is there and condition (2) is met". Fine, the resource exists, BUT condition (2) states: "Only return 304, if the date is later than current". So this condition is not met, and the page will be delivered completely.

If we hadn't received If-Modified-Since, the response would have been 304.

If the resource hadn't existed upon request, we'd have returned the appropriate code (as if there was no If-None-Match).

304 should only be returned in response for GET and HEAD requests, and all cache-related response headers have to be there. For all other types of request your server needs to be answering 412 (Precondition failed).

I hope it helps ;)



回答2:

Quoting from RFC 2616 (HTTP 1.1):

... if "*" is given and any current entity exists for that resource, then the server MUST NOT perform the requested method, unless required to do so because the resource's modification date fails to match that supplied in an If-Modified-Since header field in the request.

The RFC goes on to say that instead of performing the request, servers should respond with 304 (not modified) for GET and HEAD requests, and that they should respond with 412 (precondition failed) for all other request types. But that's only if the server actually has some version of the requested resource. If you don't have any entities, then you should handle the request (probably with a 404 since you don't have anything).

To handle a request, first figure out what the server would do if that header weren't present. If the result of that request would not be 2xx or 304, then serve the request as normal. But if the result of the request would be 2xx or 304, then handle the If-None-Modified case. When it's a star, then just return 304 immediately (unless trumped by If-Modified-Since). If it's one or more entity tags, then check whether any of those tags matches the tag of the thing you were planning on serving as a response. If there's any match, return 304; if there's no match, then serve it as you normally would.

Later in the RFC, there's more:

The meaning of "If-None-Match: *" is that the method MUST NOT be performed if the representation selected by the origin server (or by a cache, possibly using the Vary mechanism, see section 14.44) exists, and SHOULD be performed if the representation does not exist. This feature is intended to be useful in preventing races between PUT operations.

That is, the star allows the client to say, "Don't PUT this file if there's any version of this file already there."