I have a script that is consumming too much resource to provide data that could be retrieved only each minute. Is there a way to configure Apache 2 through an .htaccess file to specify headers telling to the client to keep the script result as is for one minute in its cache ?
I know this could be done through the script itself, but I would like to do this through the webserver's configuration.
mod_expires is the good solution.
If you are on a unix-like system :
a2enmod expires
apache2ctl restart
Then you will be able to define the expiration conditions for a given file, or define the cache policy according to mimetype through your .htaccess file.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/gif A3600
<Files scriptToCache.php>
ExpiresDefault A60
</Files>
</IfModule>
Here "A3600" means that the file expires 3600 seconds after access.
More information here : http://httpd.apache.org/docs/2.0/mod/mod_expires.html
Short answer is no - you need to return the caching headers from the script.
<IfModule mod_expires.c>
<FilesMatch "\.(jpe?g|png|gif|js|css)$">
ExpiresActive On
ExpiresDefault "access plus 1 year"
</FilesMatch>
</IfModule>
Related
To the following browser caching via mod_expires.c in the .htaccess...
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 day"
</IfModule>
...I would like to add an exception: One or more folders shall not be cached. I tried a version with Directory before </IfModule>, but that led to a 500 Internal Server Error. That
<Directory "/absolute/path/to/specialfolder">
ExpiresActive On
ExpiresDefault "access plus 1 seconds"
</Directory>
and that snippet
<Directory "/absolute/path/to/specialfolder">
ExpiresActive Off
</Directory>
What's wrong and what could help? (for one or a few folders)
The <Directory> directive is not permitted in a .htaccess context, it can only be used in a server (or virtualhost) context. (Hence the 500 error.)
The userland/.htaccess way would be to create another .htaccess file in that "specialfolder" with ExpiresActive Off in order to override the parent config.
Alternatively, you could perhaps use an <If> expression in the root .htaccess file.
For example:
# Turn off mod_expires for a specific directory
<If "%{REQUEST_URI} =~ m#^/specialfolder/#">
ExpiresActive Off
</If>
Where REQUEST_URI is the document-root-relative URL-path.
OR, only use mod_expires when not requesting these folder(s). For example:
# Only use mod_expires when NOT requesting the specific directories
<If "%{REQUEST_URI} !~ m#^/(specialfolder|anotherfolder)/#">
ExpiresActive On
ExpiresDefault "access plus 1 day"
</IfModule>
One or more folders shall not be cached.
Although disabling mod_expires does not necessarily prevent the resource from being cached. It simply prevents mod_expires from setting the Cache-Control (and Expires) headers. If you specifically want to disable caching then consider explicitly setting the relevant Cache-Control/Expires header(s) directly.
For example:
# Set env var when special "none-cache" folder requested:
SetEnvIf Request_URI "^/(specialfolder|anotherfolder)/" NOCACHE
# Set no-cache headers if NOCACHE env var is set
Header always set Cache-Control "no-store" env=NOCACHE
Header always set Expires "0" env=NOCACHE
In this example, you do not need to disable mod_expires since the Header directive will override mod_expires (since mod_headers is processed after mod_expires).
I have tried following code in my httpd.conf file to set the expires header in apache
<IfModule expires_module>
ExpiresActive On
ExpiresDefault A0 // have also tried "access plus 1 second"
</ifModule>
But when I look at the reponse headers it is being set to 1 year from now. Am I missing something here.
I'm making a new version of my website on a subdomain of my main site. The url of my main site is http://chirotremelo.be and my subdomain is http://v2.chirotremelo.be . My server setup is the public_html folder with within the 'old' version of the website, along with folders with images. There is also a v2 folder in this folder, containing my new version which also uses images from the standard website.
I develop my new version on my local machine, also having the v2 folder inside the main site. This is done so I can easily update it.
Now, because my v2 loads resources from the v2 version as well as the main site version, I set the <base> to http://chirotremelo.be/. To include files from the v2 folder I simply add v2/ in front of a certain url.
Locally this works nicely, but on my live version it doesn't seem to load eg http://chirotremelo.be/v2/newSite.css. The error shown is:
Imported resource from origin 'http://chirotremelo.be' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://v2.chirotremelo.be' is therefore not allowed access.
I have searched around for this but can't seem to find any solutions right away. I think it might have something to do with my .htaccess file, so here it is included:
php_value date.timezone Europe/Brussels
<FilesMatch ".php$">
AddHandler x-httpd-php54 .php
</FilesMatch>
## 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 ##
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?chirotremelo\.be/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*\.(jpe?g|gif|bmp|png)$ - [F]
RewriteCond %{HTTP_HOST} ^www.chirotremelo.be [nocase]
RewriteRule ^(.*) http://chirotremelo.be/ [last,redirect=301]
I know this might not be a lot to go on but I've never worked with subdomains before. I have successfully used http://v2.chirotremelo.be/newSite.css, but it kind of needs to be with a base of the non-subdomain to load the content that is only available on the main site.
This problem called Cross-Origin-Resource-Sharing (or CORS in short). You will find many questions here facing the problem, especially for asynchronous JavaScript requests.
It is some kind of browser related issue; the server will still serve the files requested, but the browser blocks it to prevent that a site will load "bad" content from a "bad" site. You need to send a CORS-Header with your server response to let the browser allow it.
In your case (as this is not a production site), I would advise you the following solution:
You could try to add
<IfModule mod_headers.c>
Header add Access-Control-Allow-Origin "*"
</IfModule>
to your .htaccess file. (Note, this needs mod_headers in Apache to be enabled, but I guess this is enabled by default).
This is not the best solution, especially there might be more elegant ones with redirect rules. But it should work for this special case (testing/beta site).
I'm confused on which file's rewriting rules gets hierarchy in an apache (xampp) server.
Do .htaccess rules get priority over httpd.conf rules?
If you can add the same rules to each, what is the difference between these two files?
What got me wondering about this stuff is because I'd like to update my favicon every second (for learning purposes) but the code below in my .htaccess file isn't working. My .htaccess file is in the server root folder along with my index.php file which is recognized when I go to http://localhost.
<IfModule mod_rewrite.c>
RewriteEngine On
ExpiresActive On
ExpiresByType image/x-icon "access plus 1 seconds"
</IfModule>
Any thoughts?
I have a simple RewriteRule:
RewriteRule ^/r/[0-9]+/(.*)$ /$1
This is used for cache-busting. With every web site release I change the url prefix, e.g.:
/r/17/img/image.jpg gets /img/image.jpg.
I want to apply long expiry headers to these for example
<Directory /r>
Header unset ETag
FileETag None
ExpiresDefault "access plus 1 year"
</Directory>
Of course this doesn't work because after the RewriteRule is applied, the Directory doesn't match anymore.
How can I apply these rules inside the Directory directive to URLs accessed via /r/ ?
Thanks!
The <Directory> directive is for actual existing directories and not just URL paths. Try <LocationMatch> instead:
<LocationMatch "^/r(/|$)">
Header unset ETag
FileETag None
ExpiresDefault "access plus 1 year"
</LocationMatch>
Or change /r to your actual directory /img.