304:未修改且前端缓存

发布于 2024-08-07 21:46:46 字数 918 浏览 4 评论 0原文

我正在使用 PHP 脚本来提供文件服务。 如果文件自客户端上次下载以来没有更改,我希望能够在我的 http 响应中发回 304 未修改的标头。这似乎是 Apache(以及大多数其他 Web 服务器)的一个功能,但我不知道如何通过 PHP 实现这一功能。

我听说过使用 $_SERVER['HTTP_IF_MODIFIED_SINCE'],但这个变量似乎没有出现在我的 $_SERVER 超级数组中。

我的问题不是如何返回 304 标头,而是如何知道应该返回一个标头。


编辑:问题是我的 $_SERVER['HTTP_IF_MODIFIED_SINCE'] 未设置。这是我的 .htaccess 文件的内容:

ExpiresActive On 
ExpiresByType image/jpeg "modification plus 1 month"
ExpiresByType image/png "modification plus 1 month"
ExpiresByType image/gif "modification plus 1 month"
Header append Cache-Control: "must-revalidate" 


<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteCond $1 !^(controller\.php)
   RewriteRule (.*\.jpg|.*\.png|.*\.gif) controller.php/$1
</IfModule>

HTTP_IF_MODIFIED_SINCE 仍然没有出现在 $_SERVER 超级数组中。

I am using a PHP script to serve files.
I would like to be able to send back a 304 not modified header in my http response if the file has not changed since the client last downloaded it. This seems to be a feature in Apache (and most other web servers), but I have no clue how this can be implemented through PHP.

I have heard of using $_SERVER['HTTP_IF_MODIFIED_SINCE'], but this variable does not seem to appear in my $_SERVER super array.

My question is not how to return a 304 header, but how to know that one should be returned.


Edit: The problem is that my $_SERVER['HTTP_IF_MODIFIED_SINCE'] is not set. This is the content of my .htaccess file:

ExpiresActive On 
ExpiresByType image/jpeg "modification plus 1 month"
ExpiresByType image/png "modification plus 1 month"
ExpiresByType image/gif "modification plus 1 month"
Header append Cache-Control: "must-revalidate" 


<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteCond $1 !^(controller\.php)
   RewriteRule (.*\.jpg|.*\.png|.*\.gif) controller.php/$1
</IfModule>

HTTP_IF_MODIFIED_SINCE still does not appear in the $_SERVER super array.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

淡淡的优雅 2024-08-14 21:46:46

HTTP_IF_MODIFIED_SINCE 是正确的方法。如果您没有得到它,请检查 Apache 是否有 mod_expiresmod_headers 已启用并正常工作。借用PHP.net 上的评论

$last_modified_time = filemtime($file); 
$etag = md5_file($file);
// always send headers
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT"); 
header("Etag: $etag"); 
// exit if not modified
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time || 
    @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) { 
    header("HTTP/1.1 304 Not Modified"); 
    exit; 
}

// output data

HTTP_IF_MODIFIED_SINCE is the right way to do it. If you aren't getting it, check that Apache has mod_expires and mod_headers enabled and working properly. Borrowed from a comment on PHP.net:

$last_modified_time = filemtime($file); 
$etag = md5_file($file);
// always send headers
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT"); 
header("Etag: $etag"); 
// exit if not modified
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time || 
    @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) { 
    header("HTTP/1.1 304 Not Modified"); 
    exit; 
}

// output data
沫离伤花 2024-08-14 21:46:46

本文将回答您有关缓存的所有

问题发现添加

RewriteRule .* - [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}]
RewriteRule .* - [E=HTTP_IF_NONE_MATCH:%{HTTP:If-None-Match}]

到我的 htaccess 文件的底部(在所有 rewriterule 下方)有效。

This article will answer all your questions on caching

I found that adding

RewriteRule .* - [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}]
RewriteRule .* - [E=HTTP_IF_NONE_MATCH:%{HTTP:If-None-Match}]

To the bottom of my htaccess file (below all rewriterule) worked.

涙—继续流 2024-08-14 21:46:46

我遇到了这个问题,结果只是我打开了 Firebug。默认情况下,网络选项卡“禁用浏览器缓存”下有一个选项。 Chrome的开发者工具中有一个类似的选项,菜单栏下的栏上的复选框之一。

取消勾选这些选项会导致浏览器正确发送 HTTP_IF_MODIFIED_SINCE 并且一切正常(即使 Firebug 或 Chrome 开发工具打开)。

I had this problem and it turned out to simply be that I had Firebug open. This has an option under the Net tab "Disable Browser Cache" that is ticked by default. There is a similar option in Chrome's developer tools, one of the tick boxes on the bar under the menu bar.

Unticking these options resulted in the browser correctly sending HTTP_IF_MODIFIED_SINCE and everything working fine after all (even with Firebug or Chrome Dev Tools open).

始终不够爱げ你 2024-08-14 21:46:46

register_globals 关闭时,$_SERVER['HTTP_IF_MODIFIED_SINCE'] 通常为空。

检查是否是这种情况,如果是,请尝试 getenv('HTTP_IF_MODIFIED_SINCE')

$_SERVER['HTTP_IF_MODIFIED_SINCE'] is usually empty when register_globals is off.

Check whether that's the case, and if so try getenv('HTTP_IF_MODIFIED_SINCE')

厌倦 2024-08-14 21:46:46

还有一些其他参数需要检查..在我的例子中,我没有这两个标头:

$_SERVER['HTTP_IF_NONE_MATCH'] && $_SERVER['HTTP_IF_MODIFIED_SINCE']

返回正确的 304 标头需要它们,因为我的系统时钟有点晚了,它会将这些页面解释为过期将来,然后根本不发送这些值

还要检查apache返回的标头,或者至少将其覆盖为更大的值,

Cache-Control: max-age=3600

因为它不会发送以前的标头,如果

Last-Modified previous sent header < ( NOW - 3600 )

所以在我的情况下,我已经将其设置得非常方便功能
<代码>
函数最后修改($文件){
$x=filemtime($file);
while($x>time())$x-=86000;}#如果在未来日期触及则减少一天
$date=gmdate('D, j MYH:i:s',$x).'格林威治标准时间';
header('缓存控制: max-age=86000',1);
if($_SERVER['HTTP_IF_NONE_MATCH'] == $x || $_SERVER['HTTP_IF_MODIFIED_SINCE']==$date){
header('HTTP/1.1 304 未修改',1,304);die;}
header('Etag:'.$x,1);header('最后修改时间:'.$date,1);
}

There are also some others parameters to check .. in my case I didn't had both of those headers :

$_SERVER['HTTP_IF_NONE_MATCH'] && $_SERVER['HTTP_IF_MODIFIED_SINCE']

which are required to return a proper 304 header, as my system clock was a little late, It'll interpret those pages as expiring in the future, then not sending those values at all

Also check that header which is returned by apache, or at least override it to a bigger value

Cache-Control: max-age=3600

As it won't send previous headers if

Last-Modified previous sent header < ( NOW - 3600 )

So in my case I've set this pretty handy function

function lastModified($file){
$x=filemtime($file);
while($x>time())$x-=86000;}#reduce by one day if touched in future date
$date=gmdate('D, j M Y H:i:s',$x).' GMT';
header('Cache-Control: max-age=86000',1);
if($_SERVER['HTTP_IF_NONE_MATCH'] == $x || $_SERVER['HTTP_IF_MODIFIED_SINCE']==$date){
header('HTTP/1.1 304 Not Modified',1,304);die;}
header('Etag: '.$x,1);header('Last-Modified: '.$date,1);
}

等待圉鍢 2024-08-14 21:46:46

请注意,$_SERVER["HTTP_IF_NONE_MATCH"] 可以包含引号和 -gzip 后缀。

$server_etag = str_replace("-gzip", "", str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])));

if ($server_etag == $etag) ...

Note that $_SERVER["HTTP_IF_NONE_MATCH"] can contain quotes and -gzip suffix.

$server_etag = str_replace("-gzip", "", str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])));

if ($server_etag == $etag) ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文