2010-01-18 133 views
8

我的問題是關於如何在收到 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://stackoverflow.com/questions/2000715/answering-httpifmodifiedsince-and-httpifnonematch-in-php - http://stackoverflow.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

回答

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

主要回答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