Add Expires headers for specific files in .htaccess file - .htaccess

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>

Related

Is setting Expires Header in .htacess a terrible idea for a Woocommerce site?

I have added the following to my .htacces file in order to set the expiry time for the various files types. The speed impact on my woocommerce site has been huge - it's flying now. And everything seems to work.
But surely this is a bad idea as if all the script files, thumbnails etc are cached then things shouldn't work properly one editing the cart / returning customers etc?
It just seems too easy??
# Optimize cache-control
<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 Nov 2018 10:10:10 GMT"
</IfModule>
</IfModule>
Setting up all of the expires in htaccess can break the shopping cart functionality. When this happens, customers cannot remove products from the cart or update the cart because the cart will continue to show the old contents. However, you can set some of the expires. See my example below.
#Woocommerce friendly expires
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
#
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 text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
#
ExpiresByType image/x-icon "access plus 1 year"
</IfModule>

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>

Leverage browser caching - get caching methods right

I'm trying to get the browser caching right. I added this to my .htaccess file:
<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>
I'm having the typical problem though that when updating my site, which I do quite frequently, the site doesn't update for frequent visitors. I started using URL fingerprinting for my CSS files, which works well.
However, what can I do about HTML files?
Any best practice to not run into caching troubles when updating content on any pages? I would appreciate your help!
Generally, the correct strategy (and the one used by HTML5Boilerplate) is to disable caching for HTML files, by setting the Expires time to access plus 0 seconds.

CakePHP and .htaccess Asset Caching

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.

Resources