We have a multisite CMS that handles images and other files like this..
How can we cache images and other files that are in www.(or non-www.)variable-domain.com/files/* with .htaccess?
This is causing a 500 error. I stripped out some.. here is what I have currently that works (minus the Directory and contents part - it throws the error when thats included).
#
# Force Browser Cache
#
<ifmodule mod_expires.c>
ExpiresActive On
<filesmatch "\.(jpg|gif|png|css|js)$">
ExpiresDefault "access plus 1 year"
</filesmatch>
<FilesMatch ".(flv|gif|jpg|jpeg|png|ico|swf)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
<FilesMatch ".(js|css|pdf|txt)$">
Header set Cache-Control "max-age=604800"
</FilesMatch>
<Directory "/home/aiwebsystems/public_html/uploads">
<FilesMatch "\.(gif|jpg|png|js|css)$">
ExpiresDefault "access plus 1 year"
</FilesMatch>
</Directory>
</ifmodule>
I would need all subdirectories of this included too...
Thanks for the help!
Use Apache's mod_expires
e.g in your .htaccess put:
ExpiresActive On
<Directory "/path/to/public_html/files">
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
ExpiresDefault A300
<FilesMatch "\.html$">
Expires A86400
</FilesMatch>
<FilesMatch "\.(gif|jpg|png|js|css)$">
Expires A2592000
</FilesMatch>
</Directory>
A300 meaning that the user cached copy expires 300 seconds after access. (A86400 is a day after access, A2592000 is a month after access)
If you mean server side caching, well then you are in luck as the operating system caches recently using a 'paging' algorithm: http://en.wikipedia.org/wiki/Paging
<Directory> is not allowed in htaccess.
Just create a new .htaccess file, with the expires stuff, and put it inside the 'uploads' directory. This will have the same effect you try to achief
Being as it does not have an extension, none of this worked. I change the code in the end and it works great now, using the file name rather than the image ID as the last URI parameter.
Related
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.
I have few warnings wich I'm tyring to solve in the pagespeed test, such as:
Leverage browser caching
Setting an expiry date or a maximum age in the HTTP headers for static resources instructs the browser to load previously downloaded resources from local disk rather than over the network.
And then it points out to local .js and .css files
But I have this in my htaccess:
<FilesMatch "\.(js|css|ttf)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\.(html|htm|php)$">
Header set Cache-Control "max-age=60, private, proxy-revalidate"
</FilesMatch>
<FilesMatch "\.(css|js|gif|jpeg|png|ico)$">
ExpiresActive On
ExpiresDefault "access plus 1 year"
</FilesMatch>
Any idea what i'm doing wrong?
Well, this is a shot in the dark but I came across circumstances where Apache would not respect my .htaccess headers and I had to "force" them with the always keyword like this:
<FilesMatch "\.(js|css|ttf)$">
Header always set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
Header always set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\.(html|htm|php)$">
Header always set Cache-Control "max-age=60, private, proxy-revalidate"
</FilesMatch>
<FilesMatch "\.(css|js|gif|jpeg|png|ico)$">
ExpiresActive On
ExpiresDefault "access plus 1 year"
</FilesMatch>
When your action is a function of an existing header, you may need to specify a condition of always, depending on which internal table the original header was set in. The table that corresponds to always is used for locally generated error responses as well as successful responses. Note also that repeating this directive with both conditions makes sense in some scenarios because always is not a superset of onsuccess with respect to existing headers:
You're adding a header to a locally generated non-success (non-2xx) response, such as a redirect, in which case only the table corresponding to always is used in the ultimate response.
You're modifying or removing a header generated by a CGI script, in which case the CGI scripts are in the table corresponding to always and not in the default table.
You're modifying or removing a header generated by some piece of the server but that header is not being found by the default onsuccess condition.
From Apache Module mod_headers
In my .htaccess I have this code:
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|txt|html|x-html|php|css|xml|js|woff|ttf|svg|eot)(\.gz)?$">
ExpiresActive On
Header set Expires "Sun, 27 May 2012 00:00:00 GMT"
Header unset ETag
FileETag None
</FilesMatch>
It seems to work perfectly on some servers, but not on one of my websites. I get a 500 Internal Server Error.
Is there anything wrong in the config, or do I have to contact my host?
Ensure that you have these Apache modules enabled and loaded:
ExpiresActive -- mod_expires
Header -- mod_headers
Try this instead (it will only use directives if corresponding module is present):
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|txt|html|x-html|php|css|xml|js|woff|ttf|svg|eot)(\.gz)?$">
<IfModule mod_expires.c>
ExpiresActive On
</IfModule>
<IfModule mod_headers.c>
Header set Expires "Sun, 27 May 2012 00:00:00 GMT"
Header unset ETag
</IfModule>
FileETag None
</FilesMatch>
I've been rather perplexed by this and was hoping someone might be able to shed some light.
In my htaccess file, I have:
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType text/html "access plus 4 hours"
</IfModule>
However, it doesnt seem to be working when I check the headers.
I get "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
But if I use THIS code:
# 4 HOURS
<FilesMatch "\.(html|htm)$">
Header set Cache-Control "max-age=14400, must-revalidate"
</FilesMatch>
It DOES pick up the cache.
max-age=14400, must-revalidate
Am I missing something? Is one for the server and one for the browser? I mean, I'd prefer to use the first since it came with boilerplate if they are both the same.
Thanks in advance!
I don't know if you already have the solution but are you sure mod_expire is enabled on your server? On ubuntu sudo apache2ctl -M.
You can also try to comment out <IfModule mod_expires.c> and </IfModule> and restart apache. It will crash if mod_expires is not enabled.
To enable mod_expire:
sudo a2enmod expires
mod_expires will create the Expire header and should modify the max-age=14400 part of the Cache-Control header only. For the must-revalidate part you will have to use Header.
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"