【问题标题】:browsers don't resend If-Modified-Since & If-None-Match request headers after receiving one 304 not modified response浏览器在收到一个 304 未修改响应后不发送 If-Modified-Since 和 If-None-Match 请求标头
【发布时间】:2022-10-31 10:42:34
【问题描述】:

服务器(本地开发 LAMP 服务器)端是 php ,测试的浏览器是 chromium 和 librewolf (firefox 风格),两者都显示相同的行为,因此我认为我的 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 请求标头而不是一次?

【问题讨论】:

    标签: php performance apache http-headers request-headers


    【解决方案1】:

    我终于知道了!

    标头需要与第一次发送文件时完全相同并以完全相同的顺序发送,并且可能在内容长度和响应代码之前(可能没有那么严格,但我已经花了足够的时间在这方面和我不会再调查了)

    因此,就我而言,我必须发送:

            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 了!

    希望有一天这会对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2012-11-27
      • 2011-01-07
      • 1970-01-01
      • 1970-01-01
      • 2019-08-26
      • 2023-03-31
      • 2012-03-13
      • 2018-01-27
      • 2012-01-07
      相关资源
      最近更新 更多