Answering HTTP_IF_MODIFIED_SINCE and HTTP_IF_NONE_

2019-01-10 23:40发布

I have cacheable dynamic content made in PHP 5.1.0+. I already send the correct headers (including Last-Modified and ETag) to clients.

I now want my script to be able to answer $_SERVER['HTTP_IF_MODIFIED_SINCE'] and $_SERVER['HTTP_IF_NONE_MATCH'] when present. When the conditions matches, I want to answer a HTTP 304 "Not Modified" to clients.

What are the correct conditions? When exactly I issue a 304 instead of the whole content?

The accepted answer in question How to know when to send a 304 Not Modified response seems to issue this correctly but I have hard times to port that code to PHP 5.

Thank you!

7条回答
【Aperson】
2楼-- · 2019-01-11 00:37

If I could improve slightly on the original brilliant answer from Rich Bradshaw https://stackoverflow.com/users/16511/rich-bradshaw

This code is tweaked and now 100% passes the If-Modified-Since and If-None-Match checks. It also correctly formats the Last-Modified Date as original answer sends out +0000 on the end instead of GMT and adds the VARY header to the 304 response. You can test this at redbot.org

<?php
function caching_headers ($file, $timestamp) {
    $lastModified=filemtime($_SERVER['SCRIPT_FILENAME']);
    $gmt_mtime = gmdate("D, d M Y H:i:s T", $lastModified);
    header('ETag: "'.md5($timestamp.$file).'"');
    header('Last-Modified: '.$gmt_mtime);
    header('Cache-Control: must-revalidate, proxy-revalidate, max-age=3600');

    if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
        if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime || str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == md5($timestamp.$file)) {
            header('HTTP/1.1 304 Not Modified');
            header("Vary: Accept-Encoding,User-Agent");
            exit();
        }
    }
}
caching_headers ($_SERVER['SCRIPT_FILENAME'], filemtime($_SERVER['SCRIPT_FILENAME']));
?>
查看更多
登录 后发表回答