How to Add Expires headers in Amazon CloudFront for GTmetrix? - .htaccess

Okay guys, so what I do already.I have a website (http://walshdidthat.com/) that hosted on Godaddy + using an Amazon ClounFront for static files.
I'm testing the website here - https://gtmetrix.com/reports/walshdidthat.com/OPVOSdVg
In the Yslow stats the system tell's me:
Add Expires headers , grade 0.
Please, could you give me a wording advice. In cloudfront I set TTL's, and set max-age for every uploaded file(but it's not an 'expire' variable, as I can see it now).
I have .htaccess on my host that contain:
.....
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
.... etc
Please give me an example how could I set expires setting for files on cloudfront , with example please(because I read the official documentation and they have only 1 example -' "Mon" 23:59:59 ' - that is a total BS and doesn't work.

Related

Expiration header for all files in a specific folder (.htaccess)

For all files, except pdf, in a specific directory as well as its sub-directories on the server, I would like to set the expiration header to 10 hours. How can I do this in the .htaccess file?
<Directory "/foldername">
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType * "access plus 10 hours"
</IfModule>
</Directory>
I understand Directory cannot be used in .htaccess. But how to do this?
You could put the .htaccess into the specific directory, and do it in there without any further restriction. Or use an If condition, to apply this based on what the request URI starts with.
ExpiresByType * won't work, according to the documentation, this needs an actual mime type as "argument".
But ExpiresDefault also exists, and allows you to specify the default expiry for all files.

Htaccess Expires Header in Multiple Directories

Somehow I need to confirm how htaccess expires headers works when used in the home directory as well as subdirectories.
Let's say I have this in the home directory's htaccess:
ExpiresActive On
ExpiresByType image/gif "access plus 1 month"
Then let's say I have this in an htaccess in a /thumbnails/ subdirectory:
ExpiresActive On
ExpiresByType image/gif "access plus 1 year"
So globally on the site, GIF images are meant to cache for a month, but for the /thumbnails/ directory, GIF images are meant to cache for a year. Am I correct in assuming that the htaccess in the /thumbnails/ directory will override the htaccess in the home directory? Or is it vice versa? Any documentation confirming as such?
Your assumption is correct. The Apache's documentation for any directive consists of a section called Context.
The precedence follow the rules base on AllowOverride directive. If your server is configured to allow overriding for the Expires module, then the configuration from /thumbnails/ will take precedence.

.htaccess caching issue across subdomains

I set up a subdomain on my site purely to improve site speed (to spread HTTP requests over multiple, cookieless domains, as recommended by Google). I've been experimenting and it looks like my .htaccess caching settings aren't having the same effect on the subdomain.
Compare these two URLs and their response/caching times:
http://www.scenepointblank.com/assets/img/features/coming_in_2012_homepage.png (original)
http://img.scenepointblank.com/features/coming_in_2012_homepage.png (subdomain)
Looking at the response headers it seems to have picked up the same cache_control, but the actual response times vary quite massively (I see an average of ~400ms for www and ~4s for img).
My .htaccess file is at the root of the domain and to experiment I also put a duplicate in scenepointblank.com/assets/img/ to no effect. The contents of the file are below:
FileETag MTime Size
<IfModule mod_expires.c>
# Enable expirations.
ExpiresActive On
# Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
<FilesMatch .php$>
# Do not allow PHP scripts to be cached unless they explicitly send cache
# headers themselves. Otherwise all scripts would have to overwrite the
# headers set by mod_expires if they want another caching behavior.
ExpiresActive Off
</FilesMatch>
</IfModule>
# 480 weeks
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "max-age=290304000, public"
</FilesMatch>
Any ideas why this could be happening?
Seem to have fixed this by adding the following to .htaccess:
ExpiresActive On
ExpiresByType image/png "now plus 365 days"
ExpiresByType image/jpeg "now plus 365 days"
ExpiresByType image/gif "now plus 365 days"
ExpiresByType text/css "now plus 365 days"

htaccess - How to force the client's browser to clear the cache?

For my site I have the following htaccess rules:
# BEGIN Gzip
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml text/css application/x-javascript application/javascript
</IfModule>
# END Gzip
# BEGIN EXPIRES
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 10 days"
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/plain "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-icon "access plus 1 year"
</IfModule>
# END EXPIRES
I've just updated my site and it looked all screwy until I cleared my cache. How can I force the client's browser to clear the cache after an update so that the user can see the changes?
You can force browsers to cache something, but
You can't force browsers to clear their cache.
Thus the only (AMAIK) way is to use a new URL for your resources. Something like versioning.
As other answers have said, changing the URL is a good cache busting technique, however it is alot of work to go through a bigger site, change all the URLs and also move the files.
A similar technique is to just add a version parameter to the URL string which is either a random string / number or a version number, and target the changed files only.
For instance if you change your sites CSS and it looks wonky until you do a force refresh, simply add ?ver=1.1 to the CSS import at the head of the file. This to the browser is a different file, but you only need to change the import, not the actual location or name of the file.
e.g:
<link href="assets/css/style.css" rel="stylesheet" type="text/css" />
becomes
<link href="assets/css/style.css?ver=1.1" rel="stylesheet" type="text/css" />
Works great for javascript files also.
I got your problem...
Although we can clear client browser cache completely but you can add some code to your application so that your recent changes reflect to client browser.
In your <head>:
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
You can not force the browsers to clear the cache.
Your .html file seems to be re-loaded sooner as it expires after 10 days.
What you have to do is to update your .html file and move all your files to a new folder such as version-2/ or append a version identifier to each file such as mypicture-2.jpg. Then you reference these new files in your .html file and the browser will load them again because the location changed.
You can tell the browser never cache your site by pasting following code in the header
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
And to prevent js, css cache, you could use tool to minify and obfuscate the scripts which should generate a random file name every time. That would force the browser to reload them from server too.
Hopefully, that helps.
In my case, I change a lot an specific JS file and I need it to be in its last version in all browsers where is being used.
I do not have a specific version number for this file, so I simply hash the current date and time (hour and minute) and pass it as the version number:
<script src="/js/panel/app.js?v={{ substr(md5(date("Y-m-d_Hi")),10,18) }}"></script>
I need it to be loaded every minute, but you can decide when it should be reloaded.
Adding 'random' numbers to URLs seems inelegant and expensive to me. It also spoils the URL of the pages, which can look like index.html?t=1614333283241 and btw users will have dozens of URLs cached for only one use.
I think this kind of things is what .htaccess files are meant to solve at the server side, between your functional code an the users.
I copy/paste this code from here that allows filtering by file extension to force the browser not to cache them. If you want to return to normal behavior, just delete or comment it.
Create or edit an .htaccess file on every folder you want to prevent caching, then paste this code changing file extensions to your needs, or even to match one individual file.
If the file already exists on your host be cautious modifying what's in it.
(kudos to the link)
# DISABLE CACHING
<IfModule mod_headers.c>
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires 0
</IfModule>
<FilesMatch "\.(css|flv|gif|htm|html|ico|jpe|jpeg|jpg|js|mp3|mp4|png|pdf|swf|txt)$">
<IfModule mod_expires.c>
ExpiresActive Off
</IfModule>
<IfModule mod_headers.c>
FileETag None
Header unset ETag
Header unset Pragma
Header unset Cache-Control
Header unset Last-Modified
Header set Pragma "no-cache"
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Expires "jue, 1 Jan 1970 00:00:00 GMT"
</IfModule>
</FilesMatch>
You can set "access plus 1 seconds" and that way it will refresh the next time the user enters the site. Keep the setting for one month.
Now the following wont help you with files that are already cached, but moving forward, you can use the following to easily force a request to get something new, without changing the actual filename.
# Rewrite all requests for JS and CSS files to files of the same name, without
# any numbers in them. This lets the JS and CSS be force out of cache easily
# by putting a number at the end of the filename
# e.g. a request for static/js/site-52.js will get the file static/js/site.js instead.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^static/(js|css)/([a-z]+)-([0-9]+)\.(js|css)$ /site/$1/$2.$4 [R=302,NC,L]
</IfModule>
Of course, the higher up in your folder structure you do this type of approach,
the more you kick things out of cache with a simple change.
So for example, if you store the entire css and javascript of your site in one main folder
/assets/js
/assets/css
/assets/...
Then you can could start referencing it as "assets-XXX" in your html, and use a rule like so to kick all assets content out of cache.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^assets-([a-z0-9]+)/(.*) /$2 [R=302,NC,L]
</IfModule>
Note that if you do go with this, after you have it working, change the 302 to a 301, and then caching will kick in. When it's a 302 it wont cache at the browser level because it's a temporary redirect. If you do it this way, then you could bump up the expiry default time to 30 days for all assets, since you can easily kick things out of cache by simply changing the folder name in the login page.
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault A2592000
</IfModule>
The most straight forward is to add filetime to the request.
eg
myfile.txt?2014-10-30-13:12:33
versioning by date.
Change the name of the .CSS file
Load the page and then change the file again in the original name it works for me.
This worked for me.
look for this:
DirectoryIndex index.php
replace with this:
DirectoryIndex something.php index.php
Upload and refresh page. You will get a page error.
just change it back to:
DirectoryIndex index.php
reupload and refresh page again. I checked this on all of my devices and, it worked.
Use the mod rewrite with R=301 - where you use a incremental version number:
To achieve > css/ver/file.css => css/file.css?v=ver
RewriteRule ^css/([0-9]+)/file.css$ css/file.css?v=$1 [R=301,L,QSA]
so example, css/10/file.css => css/file.css?v=10
Same can be applied to js/ files. Increment ver to force update, 301 forces re-cache
I have tested this across Chrome, Firefox, Opera etc
PS: the ?v=ver is just for readability, this does not cause the refresh

how to add mod expire condition in htaccess?

How to add mode expire condition in htaccess
You will need to make sure that you have the mod_expires module enabled, and then use the following:
ExpiresActive on
ExpiresDefault "access plus 1 month"
You can add expires times based upon content type as well, see the Apache docs for more info: http://httpd.apache.org/docs/current/mod/mod_expires.html
I assume you mean mod_expire.
Yes you can add these directives to .htaccess. So long as you have AllowOverride set
http://httpd.apache.org/docs/2.0/mod/mod_expires.html

Resources