My Laravel application is returning Cache-Control: no-cache, private
HTTP header by default for each site. How can I change this behaviour?
P.S.: It is not a PHP.ini problem, because changing session.cache_limiter
to empty/public does not change anything.
To use Cache-Control headers, choose Content Management | Cache Control Directives in the administration server. Then, using the Resource Picker, choose the directory where you want to set the headers. After setting the headers, click 'OK'.
Cache-control is an HTTP header used to specify browser caching policies in both client requests and server responses. Policies include how a resource is cached, where it's cached and its maximum age before expiring (i.e., time to live).
private. The private response directive indicates that the response can be stored only in a private cache (e.g. local caches in browsers). You should add the private directive for user-personalized content, especially for responses received after login and for sessions managed via cookies.
In Laravel headers should be set on the response object.
There's no longer any need to add your own custom middleware.
The SetCacheHeaders
middleware comes out of the box with Laravel, aliased as cache.headers
The nice thing about this Middleware is that it only applies to GET
and HEAD
requests - it will not cache POST
or PUT
requests since you almost never want to do that.
You can apply this globally easily by updating your RouteServiceProvider
:
protected function mapWebRoutes()
{
Route::middleware('web')
->middleware('cache.headers:private;max_age=3600') // added this line
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->middleware('cache.headers:private;max_age=3600') // added this line
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
I don't recommend that though. Instead, as with any middleware, you can easily apply to specific endpoints, groups, or within the controller itself, e.g.:
Route::middleware('cache.headers:private;max_age=3600')->group(function() {
Route::get('cache-for-an-hour', 'MyController@cachedMethod');
Route::get('another-route', 'MyController@alsoCached');
Route::get('third-route', 'MyController@alsoAlsoCached');
});
Note that the options are separated by semicolon not comma, and hyphens are replaced by underscores. Also, Symfony only supports a limited number of options:
'etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public', 'immutable'
In other words you can't simply copy and paste a standard Cache-Control
header value, you will need to update the formatting:
CacheControl format: private, no-cache, max-age=3600
->
Laravel/Symfony format: private;max_age=3600
You can have a global middleware for that. something like:
<?php
namespace App\Http\Middleware;
use Closure;
class CacheControl
{
public function handle($request, Closure $next)
{
$response = $next($request);
$response->header('Cache-Control', 'no-cache, must-revalidate');
// Or whatever you want it to be:
// $response->header('Cache-Control', 'max-age=100');
return $response;
}
}
then just register this as a global middleware in the Kernel file:
protected $middleware = [
....
\App\Http\Middleware\CacheControl::class
];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With