我目前正在使用以下代码通过PHP的readfile()输出一些图像文件,但是,我注意到通过Firefox和Chrome的开发工具,这些文件都没有被缓存。
ob_start();
outputfile($fp);
function outputfile( $fp ) {
header("Content-Type: $mime_type");
header("Content-Length: " . filesize($fp));
header("Cache-Control: public, max-age=3600");
header("Etag: " . md5_file($fp));
$date = gmdate("D, j M Y H:i:s", filemtime($fp))." GMT";
header("Last-Modified: $date");
readfile($fp);
exit; // tried ob_end_flush() too before exiting
}
字符串
代码输出文件,在开发工具的头文件中包含以下内容...
Cache-Control: public, max-age=2678400
Connection: keep-alive
Content-Length: 155576
Content-Type: image/jpeg
Date: Mon, 21 May 2018 22:31:02 GMT
Last-Modified: Sat, 03 Mar 2018 19:34:05 GMT
Etag: 507f2520385c009a7385a1165032bd61
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Server: nginx
型
如果我将控制权返回给Nginx来提供文件,它会输出以下头:
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 155576
Content-Type: image/jpeg
Date: Mon, 21 May 2018 22:31:02 GMT
ETag: "5a9af8ad-4a5b"
Last-Modified: Sat, 03 Mar 2018 19:34:05 GMT
Server: nginx
型
我是否错过了导致浏览器不缓存图像文件的原因?
我已经尝试添加所有必要的缓存控制头,如eTag和max-age,但浏览器只是拒绝缓存数据。我甚至尝试从服务器的输出中复制所有的头文件,并使用“ob_start('ob_gzhandler');“以防是因为原始文件数据没有被Gzip压缩。
浏览器不会缓存任何通过PHP发送的文件数据。
3条答案
按热度按时间tjjdgumg1#
我想我找到问题了...
想知道是否有任何cookie相关的代码可以影响readfile(),并发现如果我在使用该函数之前有session_start(),浏览器将拒绝缓存发送的文件数据。如果我删除session_start(),浏览器缓存会按照预期的方式工作,尊重发送的Cache-Control头。
我不太明白为什么会出现这种情况,因为我比较了readfile()的输出,在它之前有和没有session_start(),输出似乎是相同的。
我使用的是PHP 5.5。
am46iovg2#
Expires: Thu, 19 Nov 1981 08:52:00 GMT
**可能是原因。从技术上讲,如果Cache-Control
头部有一个max-age
指令,那么Expires
应该被忽略(参考:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires)的值。但是,值得通过删除该头来检查。你的PHP代码没有设置它。所以我假设它来自一些常见的配置/代码,这些代码在每个传出的响应中执行。你有没有把这个放在你的Nginx配置中,用于所有的PHP请求?
ttp71kqs3#
我知道这是一个老问题。但我遇到了同样的问题,这给了我一个线索。我的最终解决方案是去掉PHP通常发送的所有头文件,然后用我自己的只与发送的文件相关的头文件替换它们。
我开始使用header_remove();你可能会发现你并不需要所有这些头文件,或者你可能需要其他头文件。但这些是我正在发送的,我得到了正确的缓存控制。
我发送缩略图图像,我建立在飞行或拉从我自己的缓存文件夹。
字符串