浏览器(已测试 librewolf 和 chromium)在收到一个 304 未修改响应后,不会发送“如果已修改”消息,因为“如果没有匹配”

浏览器(已测试 librewolf 和 chromium)在收到一个 304 未修改响应后,不会发送“如果已修改”消息,因为“如果没有匹配”

本地主机开发服务器:

Server : Apache/2.4.46 (Unix) OpenSSL/1.1.1j PHP/8.0.3 mod_perl/2.0.11 Perl/v5.32.1

我正在使用 php 发送 etag 和上次修改的响应标头:

  "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"

当客户端再次请求同一页面时,我使用 php 捕获 if none match & if modified since request headers & can send a 304 not modified response。

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;

 } 

但是,在对同一页面的后续请求中,客户端不会发送“如果无匹配”和“如果自请求标头以来已修改”信息,而是重新加载该页面。

正如这篇博文所指出的那样http://edn.embarcadero.com/article/38123(但是关于 asp)我还使用 304(+content-length : 0响应标头)发送了相同的 etag 和未修改的标头。

但这没有帮助,因为在第三个请求中仍然没有修改

我该怎么做才能告诉客户端始终(而不是只发送一次)如果不匹配和/或如果修改自请求标头?

答案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!

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

相关内容