8

我的问题是关于当我从代理/客户端请求同时收到if-none-match 和 if-modified-since时如何回复 HTTP 304“未修改” 。

从 RFC 2616 第 14.26 节(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26):

如果没有一个实体标签匹配,那么服务器可以执行请求的方法,就好像 If-None-Match 头域不存在一样,但也必须忽略请求中的任何 If-Modified-Since 头域。也就是说,如果没有实体标签匹配,则服务器不得返回 304(未修改)响应。

我不确定是否理解此声明...

  1. PHP 中的“如果没有一个实体标签匹配”他们说的$_SERVER['HTTP_IF_NONE_MATCH']是我之前发送的我的 ETags 吗?
  2. 如果我正确理解了这句话,只要列出的 ETag$_SERVER['HTTP_IF_NONE_MATCH']与我的 ETag 都不匹配,我就会停止所有验证并正常提供页面。

任何人都可以用伪代码(或 PHP 代码)翻译这个 RFC 部分和/或回答我上面的 2 点吗?

编辑 1: 感谢 St.Woland 的回答。您(或其他任何人)能否告诉我我在这 6 点上是否正确:

  1. 的格式$_SERVER['HTTP_IF_NONE_MATCH']可以是:

    a)If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"

    b) If-None-Match: "xyzzy"

    并不是:

    c) If-None-Match: "xyzzy, r2d2xxxx, c3piozzzz"

  2. 如果!array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER),则 anyTagMatched() 返回 NULL。

  3. 只要 ETag$_SERVER['HTTP_IF_NONE_MATCH']与我的文档 ETag 匹配,anyTagMatched() 就会返回 TRUE。

  4. 如果没有任何 Etag$_SERVER['HTTP_IF_NONE_MATCH']与我的文档 ETag 匹配,则anyTagMatched()返回 FALSE。

  5. 如果$_SERVER['HTTP_IF_MODIFIED_SINCE']设置并匹配我的文档“最后修改”日期isExpired()返回 FALSE,否则返回 TRUE。

  6. 一旦anyTagMatched()返回 TRUE,我就会发出 304。如果 anyTagMatched() 返回 NULL 并isExpired()返回 FALSE,我可以发出 304。在任何其他情况下,我都会照常提供我的页面(我还发出最新的 Last-Modified 和ETag 标头)。

4

1 回答 1

5

这应该放在最后(为了更好看而移动)。

$anyTagMatched = anyTagMatched() ;
if( $anyTagMatched || ( ( null === $anyTagMatched ) && !isExpired() ) ) {
    notModified() ;
}
// Output content

伪代码(需要审查):

<?php

/**
 * Calculates eTag for the current resource.
 */
function calculateTag() {
}

/**
 * Gets date of the most recent change.
 */
function lastChanged() {
}

/**
 * TRUE if any tag matched
 * FALSE if none matched
 * NULL if header is not specified
 */
function anyTagMatched() {
    $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
        stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : 
        false ;

    if( false !== $if_none_match ) {
        $tags = split( ", ", $if_none_match ) ;
        $myTag = calculateTag() ;
        foreach( $tags as $tag ) {
            if( $tag == $myTag ) return true ;
        }
        return false ;
    }
    return null ;
}

function isExpired() {
    $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
        stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) :
        false;

    if( false !== $if_modified_since ) {
        // Compare time here; pseudocode.
        return ( $if_modified_since < lastChanged() ) ;
    }

    return true ;
}

function notModified() {
    header('HTTP/1.0 304 Not Modified');
    exit ;
}

主要答案在这里

于 2010-01-18T15:05:50.117 回答