我正在建设的网站在图库中提供了大量图片。我想为这些图像使用浏览器缓存功能。我的后端基于REST的原理,我使用控制器方法来提供图像。
// check if the client validating cache and if it is current
$ifModified = Request::header('If-Modified-Since');
if (isset($ifModified) && (strtotime($ifModified) == filemtime($filePath . $fileName))) {
// cache IS current, respond 304
header('HTTP/1.0 304 Not Modified');
exit();
} else {
return new BinaryFileResponse(readfile($filePath . $fileName), 200,
array(
'Content-Type' => 'image/jpeg', // Guessing probably all jpegs.
'Content-Transfer-Encoding' => 'binary',
'Content-Disposition' => 'inline; filename="' . $fileName . '"',
'Content-Length' => filesize($filePath . $fileName),
'Expires' => date(DATE_RFC822, strtotime("+2 days")),
'Last-Modified' => date(DATE_RFC822, \Illuminate\Support\Facades\File::lastModified($filePath . $fileName)),
'Cache-Control' => 'public, max-age=10800, pre-check=10800',
'Pragma' => 'public',
), true, 'inline');
}
通过我的localhost运行时,响应头是:
HTTP/1.1 200 OK
Date: Mon, 05 May 2014 18:12:56 GMT
Server: Apache/2.4.4 (Win64) PHP/5.4.12
X-Powered-By: PHP/5.4.12
Content-Transfer-Encoding: binary
Content-Disposition: inline; filename="2930..jpg"
Content-Length: 17080
Expires: Wed, 07 May 14 18:12:57 +0000
Cache-Control: max-age=10800, pre-check=10800, public
Last-Modified: Mon, 05 May 14 11:43:08 +0000
Pragma: public
X-Frame-Options: SAMEORIGIN
X-UA-Compatible: IE=edge,chrome=1
Keep-Alive: timeout=5, max=97
Connection: Keep-Alive
Content-Type: image/jpeg
通过我的托管服务提供商运行网站时,响应标头为:
HTTP/1.1 200 OK
Date: Mon, 05 May 2014 18:29:24 GMT
Server: Apache/2.2.27 (Unix) mod_ssl/2.2.27 OpenSSL/1.0.1e-fips mod_bwlimited/1.4
X-Powered-By: PHP/5.4.27
Cache-Control: max-age=0
Expires: Mon, 05 May 2014 18:29:24 GMT
X-UA-Compatible: IE=edge,chrome=1
Keep-Alive: timeout=5, max=96
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
我正在使用.htaccess文件,在localhost和我的托管服务提供商上都是相同的。除了Apache和PHP版本的差异,我猜这可能是服务器配置问题。为了找出为什么主机上运行的后端没有向客户端传输正确的标头,我该查找什么?
答案 0 :(得分:0)
看看这个问题:Cannot set Cache-Control in Laravel 4
他们建议您使用BinaryFileResponse
,但他们会使用该类的实际方法来设置各种设置。解析你传递的价值可能是一个问题。
答案 1 :(得分:0)
我的坏。我是个骗子!
此代码有效:
// check if the client validating cache and if it is current
$ifModified = Request::header('If-Modified-Since');
if (isset($ifModified) && (strtotime($ifModified) == filemtime($filePath . $fileName))) {
// cache IS current, respond 304
header('HTTP/1.0 304 Not Modified');
exit();
} else {
return new BinaryFileResponse($filePath . $fileName, 200,
array(
'Content-Type' => 'image/jpeg', // Guessing probably all jpegs.
'Content-Transfer-Encoding' => 'binary',
'Content-Disposition' => 'inline; filename="' . $fileName . '"',
'Content-Length' => filesize($filePath . $fileName),
'Expires' => date(DATE_RFC822, strtotime("+2 days")),
'Last-Modified' => date(DATE_RFC822, \Illuminate\Support\Facades\File::lastModified($filePath . $fileName)),
'Cache-Control' => 'public, max-age=10800, pre-check=10800',
'Pragma' => 'public',
), true, 'inline');
}
由于我正在返回二进制文件响应,我当然不应该在移交之前读取该文件。响应构造函数需要文件名,而不是数据。 无论如何,这揭示了响应头根本没有任何问题。
响应失败,我相应地得到了标题。但是,由于我从图像文件中读取数据,因此无论如何数据仍然是请求的主体。这就是我没有发现错误的原因。