apache 在收到一个304未修改响应后,浏览器不重新发送If-Modified-Since和If-None-Match请求标头

ldioqlga  于 2022-11-16  发布在  Apache
关注(0)|答案(1)|浏览(221)

服务器(本地开发LAMP服务器)端是php,测试的浏览器是chrome & librewolf(firefox flavour),两者都显示相同的行为,因此我认为我的http头有问题。
第一次请求时发送的标头:
由我的代码:

"Connection    : close"
      "Content-Type  : text/html; charset=UTF-8"
      "Date          : ".gmdate("D, d M Y H:i:s")." GMT";
      "Last-Modified : ".$lastmod;
      "Etag          : ".$etag;
      "Expires       : 1" //can't have the browser doesn't check if file was modified on server
      "Pragma        : public"
      "Cache-Control : max-age=1,must-revalidate"

通过ob_start("ob_gzhandler")

"Content-Encoding : gzip"

通过Apache服务器:

"Connection        : Keep-Alive"
     "Keep-Alive        : timeout=5, max=99"
     "Server            : Apache/2.4.46 (Unix) OpenSSL/1.1.1j PHP/8.0.3 mod_perl/2.0.11 Perl/v5.32.1"
     "Transfer-Encoding : chunked"
     "Vary              : Accept-Encoding"
     "X-Powered-By      : PHP/8.0.3"

服务器检查客户端是否缓存了文件:

if (
    ((isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) 
      &&  $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $lastmod )
    || 
    (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) 
    && isset($_SERVER['HTTP_IF_NONE_MATCH'])
    && trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag)
    )
  )
    {
       
       header("HTTP/1.1 304 Not Modified");
       header("Content-Length:0");
       header('Etag:'. $etag);
       header('Last-Modified:'.$lastmod);

       exit;

     }

第一次librewolf(firefox)和chromium重新请求页面时,它们按预期发送If-Modified-Since和/或If-None-Match请求报头,并按预期接收304 not modified报头。
然而,在第一次重新请求之后,在接收到一个304 not modified响应之后,它们不再发送那些If-Modified-Since和/或If-None-Match请求报头,使得该缓存系统有一半的时间是无用的。

如何让客户端浏览器始终发送这些If-Modified-Since和/或If-None-Match请求标头,而不是只发送一次?

0mkxixxg

0mkxixxg1#

我终于知道了!
标头需要完全相同&以与第一次发送文件时完全相同的顺序发送,并且可能在内容长度和响应代码之前(也许这没有那么严格,但我已经在这方面花了足够的时间,我不打算再研究了)
因此,在我的情况下,我必须发送:

header("Connection:close");
        header("Date:".gmdate('D, d M Y H:i:s')." GMT");
        header('Last-Modified:'.$lastmod);
        header('Etag:'. $etag);
        header("Expires:".gmdate('D, d M Y H:i:s',parent::$requesttime+self::$expire));
        header("Pragma:public");
        header("Cache-Control:max-age=".self::$expire.",  must-revalidate");
        header("Content-Length:0");
        header("HTTP/1.1 304 Not Modified");

&宾果终于...没有更多不必要的200!
希望有一天这能对某人有所帮助。

相关问题