【问题标题】:Cache headers not sent to client缓存标头未发送到客户端
【发布时间】:2014-05-07 20:17:45
【问题描述】:

我正在构建的网站在图库中提供大量图片。我想为这些图像使用浏览器缓存功能。我的后端基于 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');
}

当通过我的本地主机运行时,响应头是:

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 版本的差异之外,我猜这可能是服务器配置问题。为了找出主机上运行的后端未将正确的标头传输到客户端的原因,我应该寻找什么?

【问题讨论】:

  • 您知道单独发送这些标头不会完成全部工作,对吧?您还必须相应地回答 有条件的 GET 请求。
  • 不确定您指的是什么...我正在检查是否存在“If-Modified-Since”请求标头,如果文件未更改,则快速返回 304 NOT MODIFIED。我只是没有包含那段代码。这是你的意思吗?
  • 我已经更新了上面的响应方法以反映我也在处理 If-Modified-Since 请求标头
  • 是的,我就是这个意思。如果你已经处理好了,很好。

标签: php apache .htaccess caching laravel


【解决方案1】:

看看这个问题:Cannot set Cache-Control in Laravel 4

他们建议像您一样使用BinaryFileResponse,但他们正在使用该类的实际方法来设置各种设置。也许这是解析您传递的值的问题。

【讨论】:

  • 但是为什么我的本地主机解析值很好,而不是我的托管服务提供商?基于在 localhost 上运行时实际发送标头的事实,我认为这可能不是 Laravel 错误。我在两个实例中都使用相同版本的框架...
  • 这很奇怪。也许它是 PHP 设置或主机设置。我会为你进一步研究。
【解决方案2】:

我的错。我真是个蓝精灵!

此代码有效:

// 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');
}

由于我返回的是二进制文件响应,所以我当然不应该在移交文件之前阅读该文件。响应构造函数需要一个文件名,而不是数据。 无论如何,这发现响应标头根本没有任何问题。

响应失败,我得到了相应的标题。但是由于我从图像文件中读取了数据,因此数据无论如何都会作为请求的主体。这就是我没有发现错误的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-14
    • 2021-06-18
    • 2021-09-11
    • 2018-05-25
    • 2021-06-27
    • 1970-01-01
    • 2022-01-14
    相关资源
    最近更新 更多