15

出于某种原因,Laravel 似乎在最后一刻操纵了响应标头“Cache-Control”。我想让浏览器缓存成为可能。

class TestController extends Controller
{

    public function getTest()
    {
        $response = new \Illuminate\Http\Response('test', 200, array(
            'Cache-Control' => 'max-age='.(config('imagecache.lifetime')*60).', public',
            'Content-Length' => strlen('test'),
        ));

        $response->setLastModified(new \DateTime('now'));
        $response->setExpires(\Carbon\Carbon::now()->addMinutes(config('imagecache.lifetime')));

        return $response;
     }
}

即使我使用“后中间件”并死掉并转储响应,我仍然会得到这个,这对我来说似乎是正确的。

Response {#625 ▼
  +original: "test"
  +exception: null
  +headers: ResponseHeaderBag {#626 ▼
    #computedCacheControl: array:2 [▼
      "max-age" => "2592000"
      "public" => true
    ]
    #cookies: []
    #headerNames: array:5 [▶]
    #headers: array:5 [▼
      "cache-control" => array:1 [▼
        0 => "max-age=2592000, public"
      ]
      "content-length" => array:1 [▼
        0 => 4
      ]
      "date" => array:1 [▶]
      "last-modified" => array:1 [▼
        0 => "Sun, 16 Aug 2015 15:42:08 GMT"
      ]
      "expires" => array:1 [▶]
    ]
    #cacheControl: array:2 [▼
      "max-age" => "2592000"
      "public" => true
    ]
  }
  #content: "test"
  #version: "1.0"
  #statusCode: 200
  #statusText: "OK"
  #charset: null
}

$response->isCacheable() 方法也返回 true。但是当我收到响应时,Firebug 显示以下内容:

Cache-Control   
no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection  
Keep-Alive
Content-Type    
text/html
Date    
Sun, 16 Aug 2015 15:42:08 GMT
Expires 
Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive  
timeout=5, max=98
Pragma  
no-cache
Server  
Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.5.15
Transfer-Encoding   
chunked
X-Powered-By    
PHP/5.5.15

我使用 xampp,但在同一台服务器上,当我只加载一个 html 页面(没有 Laravel/PHP)时,它不会发送这些 Cache-Control 标头。

当我设置 last-modified 和 expires 标头时,如何实现浏览器不接收 Cache-Control 标头“no-store, no-cache”?

谢谢!

4

2 回答 2

7

我相信您的幻像缓存控制标头来自 PHP。

http://php.net/manual/en/function.session-cache-limiter.php

当 php.ini 将session.cache_limiter设置为 nocache(默认)时,PHP 设置以下标头:

Expires: Thu, 19 Nov 1981 08:52:00 GMT 
Cache-Control: no-store,no-cache, must-revalidate, post-check=0, pre-check=0 
Pragma: no-cache

几天来,我一直在 apache 上的 laravel 中为缓存控制而苦苦挣扎:我发现在 laravel 中设置标头只是将它们附加到由 php.ini 设置的标头上。我尝试在 apache.conf 中设置一些规则,以允许缓存通过 laravel 访问的 .js 和 .css 文件,同时防止缓存对 .php 文件的请求,但是这些规则失败了,因为 apache 会看到任何文件通过 laravel 作为 .php 文件提供服务(因为它是通过 index.php 访问的)。

最后,我决定在 php.ini 中将 session.cache_limiter 设置为 '' (从而跳过 PHP 对缓存头的处理),并将以下内容添加到 app:after() 中的 filters.php

     /*
     * Custom cache headers for js and css files
     */
    if ($request->is('*.js') || $request->is('*.css')){
        $response->header("pragma", "private");
        $response->header("Cache-Control", " private, max-age=86400");
    } else {
        $response->header("pragma", "no-cache");
        $response->header("Cache-Control", "no-store,no-cache, must-revalidate, post-check=0, pre-check=0");
    }
于 2017-09-07T20:13:04.430 回答
2

尽管我不知道您的确切配置,但我认为这是由于您的 Apache 配置造成的,因为可以在那里覆盖标头值。

查看所有 Apache 配置文件并注意以 开头的行Header Set Cache-Control,例如Header Set Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"

可能这样的指令设置为仅影响您的 PHP 文件,这将是其他文件与其他标头一起交付的原因。

但是:更改此设置时要小心。出于安全原因,您可能希望设置此项。考虑通过代理缓存动态的、经过身份验证的内容的问题(详细链接)

于 2015-09-02T19:07:55.253 回答