HTTP if-none-match和if-modified-since和304在PHP中的说明

问题描述:

我的问题是关于如何在收到 if-none-match和if-modified-因为来自代理/客户端请求。HTTP if-none-match和if-modified-since和304在PHP中的说明

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

如果没有实体标签相匹配,那么 服务器可以犹如如果-None-Match头 场没有执行请求 方法存在,但也必须忽略请求中的任何If-Modified-Since报头字段 。也就是说,如果 没有实体标签匹配,那么服务器 绝不能返回304(未修改) 响应。

我不知道要了解本声明

  1. “如果没有实体标签匹配的”,在PHP?他们讲的$_SERVER['HTTP_IF_NONE_MATCH']与我的ETag我较早前寄出?
  2. 如果我理解正确的话,只要没有在$_SERVER['HTTP_IF_NONE_MATCH']中列出的ETag与我的ETags匹配,我就会停止所有验证并正常提供页面。

任何人都可以在伪代码(或PHP代码)中翻译此RFC部分和/或回答我的2点以上?

编辑1: 感谢St.Woland的回答。您(或其他人)能告诉我,如果我正确的这6个点:

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

    a)如果 - 无 - 匹配:“XYZZY” “r2d2xxxx”, “c3piozzzz”

    b)若 - 无 - 匹配: “XYZZY”

    和NOT:

    c)若 - 无 - 匹配:“XYZZY,R2 d2xxxx,c3piozzzz“

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

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

  4. 如果$_SERVER['HTTP_IF_NONE_MATCH']中的Etags都不匹配我的文档ETag,则anyTagMatched()返回FALSE。

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

  6. 只要anyTagMatched()返回TRUE,我发出304.如果anyTagMatched()返回NULL和isExpired()返回FALSE我可以发出304。在任何其他情况下,我都会像往常一样为我的页面提供服务(我还发行最新的Last-Modified和ETag标题)。

+0

看看: - http://*.com/questions/2000715/answering-httpifmodifiedsince-and-httpifnonematch-in-php - http://*.com/questions/1583740/304-未修改前端缓存 – 2010-01-18 14:45:55

+1

根据定义,未加引号的值无效(请参阅http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.11)。 – Gumbo 2010-01-26 19:36:49

+0

很高兴知道,我应该学会阅读RFC中的这些字段定义!点“1-C”仍然是无效的权利? – AlexV 2010-01-26 20:09:59

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

$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 ; 
} 

主要回答here

+0

在你的isExpired()函数中,如果$ if_modified_since == false?该函数不返回任何东西... – AlexV 2010-01-21 16:44:03

+0

它显然应该返回'true',因为IF-MODIFIED-SINCE头没有设置。我已经相应地更改了代码。对不起,这真的需要更深入的检查,但这就是你要求的:伪代码。 – 2010-01-21 21:22:38

+0

添加了问题中的“编辑1”。如果你有时间确认我的观点,那将是非常棒的。非常感谢! – AlexV 2010-01-26 19:20:33