CakePHP and .htaccess Asset Caching - .htaccess

I am still pretty new to CakePHP and am having trouble figuring out how to optimize asset caching.
Back when I still coded in pure PHP, this is what I would do with my .htaccess and header.inc.php files:
.htaccess:
<IfModule mod_rewrite.c>
# Turn the rewrite engine on
RewriteEngine On
# The following rewrite rule makes it so that if a URL such as
# http://example.com/css/style.1291314030.css is requested
# then it will actually load the following URL instead (if it exists):
#
# http://example.com/css/style.css
#
# This is to increase the efficiency of caching. See http://bit.ly/9ZMVL for
# more information.
RewriteCond %{DOCUMENT_ROOT}/$1/$2.$3 -f
RewriteRule ^(css|js)/(.*)\.[0-9]+\.(.*)$ /$1/$2.$3 [L]
</IfModule>
<IfModule mod_expires.c>
# Optimize caching - see http://yhoo.it/ahEkX9 for more information.
ExpiresActive On
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 month"
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType application/x-javascript "access plus 1 year"
</IfModule>
header.inc.php:
foreach ($css_to_use as $current_css)
{
echo "\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/$current_css." . filemtime("{$_SERVER['DOCUMENT_ROOT']}/css/$current_css.css") . ".css\">";
}
This setup worked quite well because when I worked on client websites, I never had to tell the client to perform a hard refresh or clear their cache; it was totally automatic and still had the benefits of caching.
I see that in CakePHP's "app/config/core.php" file, one can use this line of code:
Configure::write('Asset.timestamp', 'force');
However, that only makes the URLs look like this:
<link rel="stylesheet" type="text/css" href="/css/style.css?1291314030" />
So it doesn't work the way I'd like it to. What is the best way to achieve asset caching?
Thanks!

Appending a query string is effectively the same as changing the url, browsers will consider it different and reload the asset, be it CSS, images or anything else.

Step 1: Change your webroot .htacess to this
## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresDefault "access plus 2 days"
</IfModule>
## EXPIRES CACHING ##
Step 2: sudo a2enmod expires
Step 3: sudo service apache2 restart
Step 4: Drink a beer, life is good.

Related

Add Expires headers for specific files in .htaccess file

I'm trying to add browser caching rules to my .htaccess file, with different expiry rules for files in a certain directory. The general rules are being applied OK but the directory specific rules are not.
This is the section in my .htaccess file (the FilesMatch rule is to target the directory):
<IfModule mod_expires.c>
ExpiresActive On
# Images
ExpiresByType image/jpeg "access plus 1 day"
ExpiresByType image/gif "access plus 1 day"
ExpiresByType image/png "access plus 1 day"
ExpiresByType image/webp "access plus 1 day"
ExpiresByType image/svg+xml "access plus 1 day"
ExpiresByType image/x-icon "access plus 1 day"
# CSS, JavaScript
<FilesMatch "^(assets/foundation/5.5.3)$">
ExpiresByType text/css "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
</FilesMatch>
ExpiresByType text/css "access plus 1 day"
ExpiresByType text/javascript "access plus 1 day"
ExpiresByType application/javascript "access plus 1 day"
# Others
ExpiresByType application/pdf "access plus 1 day"
</IfModule>
These are the files I'm trying to target:
https://cm.anyware.co.nz/assets/foundation/5.5.3/css/normalize.css
https://cm.anyware.co.nz/assets/foundation/5.5.3/css/foundation.min.css
https://cm.anyware.co.nz/assets/foundation/5.5.3/js/vendor/modernizr.js
https://cm.anyware.co.nz/assets/foundation/5.5.3/js/vendor/jquery.js
https://cm.anyware.co.nz/assets/foundation/5.5.3/js/foundation.min.js
https://cm.anyware.co.nz/assets/foundation/5.5.3/js/foundation.dropdown.js
https://cm.anyware.co.nz/assets/foundation/5.5.3/js/foundation.topbar.js
GTMetrix says these static components do not have a far-future expiration date.
What am I doing wrong please?
<FilesMatch "^(assets/foundation/5.5.3)$">
The <FilesMatch> (and <Files>) directive matches against the filename only, eg, normalize.css, foundation.min.css, etc. which is not what you require.
The easiest way to target this specific directory only is to create another .htaccess file in this directory with the necessary overrides.
Alternatively, you can use an Apache Expression on Apache 2.4+ and check against the REQUEST_URI, although this isn't necessarily the same as the directory (depending on your system).
For example:
<If "%{REQUEST_URI} =~ m#^/assets/foundation/5\.5\.3/#">
ExpiresByType text/css "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
</If>

How to prevent .htaccess holding codeigniter session data

I have website built on Codeigniter and on product page which has loads of images etc so I setup htaccess caching as following:
## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
</IfModule>
## EXPIRES CACHING ##
<IfModule mod_deflate.c>
However issue is when customer go through the check out process and place order I am using codeigniter sess_destroy to destroy use session. However when I go back to product URL it shows there is items in cart. When I click to check out again. I have nothing in my cart which means codeigniter did destroy the session.
How to resolve this? Please help

Set an .htaccess file for every directory

I'm working on multiple subdomains on my domain. I just finished working on one and want to specify cache headers for this specific subdomain. I dont want the other subdomains to also enable the cache headers, just the single one i finished working on.
So, expire headers should work for subdomain A, but not for subdomain B and C.
I have no clue how to achieve this and can't find a similar question.
My current .htaccess file
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# Default directive
ExpiresDefault "access plus 1 month"
# My favicon
ExpiresByType image/x-icon "access plus 1 year"
# Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 month"
# Javascript
ExpiresByType application/javascript "access plus 1 year"
</IfModule>
You can use the <If> directive in htaccess context to match against the HTTP_HOST variable:
<If "%{HTTP_HOST} =~ /(www\.)?subdomainA\.example\.com$/">
# List of expires directives here
</If>

Adding Expires Headers and .htaccess

I'm trying to optimise a WordPress site of mine - Type & Music based on reports I've been getting from GTmetrix. One of the things I'm being advised to do is add expires headers and leverage browser caching. I may be wrong, but I assume these are kind of the same thing?
Anyways, I've been looking at tutorials online such as How to Add Far Future Expires Headers to Your WordPress Site and How to Leverage Browser Caching in WordPress via .htaccess from Thomas Griffen Media, which all seem to be just a case of copy and paste (I am aware that the settings are specific to each site though, depending how how regularly you update/edit certain content and files) but these settings never seem to register at all when I retest the site.
Here are the contents of my .htaccess file:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 month”
ExpiresByType image/jpeg "access 1 month”
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 week”
ExpiresByType text/css "access 1 week”
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 week"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 2 days"
</IfModule>
## EXPIRES CACHING ##
I have since installed the Quick Cache plugin too, but to the best of my knowledge that doesn't really conflict, especially since the settings in my htaccess file aren't registering in the first place.
Any help would be greatly appreciated as I've found nothing of help myself.
Here's what you need to add to your .htaccess file in order to get rid of this problem. This is the entire script for most type of files. Hope this helps.
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType text/html "access plus 3 days"
ExpiresByType text/xml "access plus 1 seconds"
ExpiresByType text/plain "access plus 1 seconds"
ExpiresByType application/xml "access plus 1 seconds"
ExpiresByType application/rss+xml "access plus 1 seconds"
ExpiresByType application/json "access plus 1 seconds"
ExpiresByType text/css "access plus 1 week"
ExpiresByType text/javascript "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
ExpiresByType application/x-javascript "access plus 1 week"
ExpiresByType image/x-ico "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresByType application/pdf "access plus 1 month"
<IfModule mod_headers.c>
Header unset ETag
Header unset Pragma
Header unset Last-Modified
Header append Cache-Control "public, no-transform, must-revalidate"
Header set Last-modified "Tue, 1 Oct 2014 10:10:10 GMT"
</IfModule>
</IfModule>
The problem has to do with missing Apache2 Modules on your LAMP server (specifically mod_headers and mod_expires). If you can get in via SSH, go there and access root through the following command:
sudo -i
Then paste in the following to enable Mod Headers:
sudo a2enmod headers
You will then see this message: To activate the new configuration, you need to run: service apache2 restart
Paste in the command below to restart:
service apache2 restart
Next, paste the command below to enable content caching:
sudo a2enmod expires
Restart again with what you see below and you will be good:
service apache2 restart
That's it. Everything hosted on your server should now be caching correctly. Note that if you're using a CDN, you will need to go there and specify a far future cache date as well. If you're using MaxCDN, you just navigate to Zones > Pull Zones > Settings > Cache Settings, then dictate 12 months.

.htaccess - Set expire headers while url rewriting

I'm rewriting using htaccess like:
# ENABLE REWRITE
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteRule ^gallery/(.+)$ /image.php?image=$1 [L,QSA,NC]
# EXPIRES CACHING
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
</IfModule>
As you can see, I'm also setting expire period using .htaccess. Expire works if I remove line RewriteRule ^gallery/(.+)$ /image.php?image=$1 [L,QSA,NC], but then obviously I will have problem with rewriting. How can I combine this two things to play well together?
I'm on LiteSpeed server.
You can try this FilesMatch directive for the rewritten PHP file:
<FilesMatch "image\.php$">
ExpiresDefault "access plus 1 year"
</FilesMatch>

Resources