我正在通过php提供图像并且在设置它时会出现一些问题,以便使用304标头进行响应以节省加载时间。
我在php.net上找到的大部分代码。它可以工作,但总是以200响应。由于某种原因,即使我最初发送Last-Modified标头,也没有收到任何请求的If-Modified-Since标头。这是在一个apache服务器。知道什么可能是错的吗?
此页面将从磁盘加载图像并将其显示到浏览器,同时发送Last-Modified标头。如果刷新页面,浏览器不会像它应该发送If-Modified-Since标头。
define('SITEPATH', (dirname($_SERVER['SCRIPT_NAME']) == '/') ? '/' : dirname($_SERVER['SCRIPT_NAME']).'/');
$load_path = $_SERVER['DOCUMENT_ROOT'] . SITEPATH . 'fpo_image.jpg';
// Get headers sent by the client.
$headers = apache_request_headers();
$file_time = filemtime($load_path);
header('Cache-Control: must-revalidate');
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $file_time).' GMT');
if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == $file_time)) {
header('HTTP/1.1 304 Not Modified');
header('Connection: close');
} else {
header('HTTP/1.1 200 OK');
header('Content-Length: '. filesize($load_path));
header('Content-type: image/jpeg');
readfile($load_path);
}
答案 0 :(得分:6)
Mandor dot net上的mandor posted a solution在PHP.net文档中为我工作的标题函数:
<?php
// Test image.
$fn = '/test/foo.png';
// Getting headers sent by the client.
$headers = apache_request_headers();
// Checking if the client is validating his cache and if it is current.
if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == filemtime($fn))) {
// Client's cache IS current, so we just respond '304 Not Modified'.
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($fn)).' GMT', true, 304);
} else {
// Image not cached or cache outdated, we respond '200 OK' and output the image.
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($fn)).' GMT', true, 200);
header('Content-Length: '.filesize($fn));
header('Content-Type: image/png');
print file_get_contents($fn);
}
?>
答案 1 :(得分:2)
我认为应该是
if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) >= $file_time)) {
检查修改时间是否大于或等于而不是等于。虽然我明白这两个值应该是相同的。
答案 2 :(得分:1)
经过一段时间的搜索,我找到了答案。在我发送以下标题之前,浏览器没有缓存任何内容(并且没有发送If-Modified-Since
):
Cache-Control: private;
这样做之后一切正常。
答案 3 :(得分:1)
我不得不使用Keith的解决方案,结合上面的azkotoki和Zsolti的帖子,使一切都按要求工作。
所以,最后一个例子是:
<?php
// Test image.
$fn = '/test/foo.png';
session_cache_limiter(false);
header('Cache-Control: private');
// Getting headers sent by the client.
$headers = apache_request_headers();
// Checking if the client is validating his cache and if it is current.
if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == filemtime($fn))) {
// Client's cache IS current, so we just respond '304 Not Modified'.
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($fn)).' GMT', true, 304);
} else {
// Image not cached or cache outdated, we respond '200 OK' and output the image.
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($fn)).' GMT', true, 200);
header('Content-Length: '.filesize($fn));
header('Content-Type: image/png');
print file_get_contents($fn);
}
?>
答案 4 :(得分:0)
检查该页面上是否正在使用会话,如果是,请尝试:
session_cache_limiter(false);
如果上述方法有效,请在下面解释:
Php的会话机制发送一些与缓存相关的自动头文件,以改善会话cookie隐私,避免被中间代理缓存:
http://php.net/manual/en/function.session-cache-limiter.php
这些自动标头导致浏览器不发送If-Modified-Since标头,因为它们指示它根本不执行任何缓存。