header expire on javascript files not working - apache

I can't get the expire header on JS files to work properly.. It works fine on eg CSS files!?
Could anybody tell me what Im doing wrong? :(
htaccess
ExpiresActive on
ExpiresDefault A0
ExpiresByType image/gif A29030400
ExpiresByType image/jpeg A29030400
ExpiresByType image/png A29030400
ExpiresByType text/css A29030400
ExpiresByType text/javascript A29030400
ExpiresByType application/x-javascript A29030400
header on CSS file
Cache-Control max-age=29030400
Connection Keep-Alive
Date Sun, 14 Oct 2012 12:06:45 GMT
Etag "be-4cbcf2ad48b40"
Expires Sun, 15 Sep 2013 12:06:45 GMT
Keep-Alive timeout=5, max=97
Server Apache/2.4.2 (Win64) PHP/5.4.3
header on JS file
Cache-Control max-age=0
Connection Keep-Alive
Date Sun, 14 Oct 2012 12:06:45 GMT
Etag "1ad-4cc00d069f493"
Expires Sun, 14 Oct 2012 12:06:45 GMT
Keep-Alive timeout=5, max=99
Server Apache/2.4.2 (Win64) PHP/5.4.3

(can't comment yet...)
I run the following settings and it works.
ExpiresByType text/js "access plus 1 years"
ExpiresByType text/javascript "access plus 1 years"
ExpiresByType application/javascript "access plus 1 years"
ExpiresByType application/x-javascript "access plus 1 years"
Should work
Cheers
Robin

Try wrapping an ExpiresDefault in a <filesMatch tag instead of using ExpiresByType :
<filesMatch "\.(js)$">
ExpiresDefault A29030400
</filesMatch>

You might need to activate the Expires module from inside your Apache host configuration.
In my case, I added
ExpiresActive On
right before the first ExpiresByType directive and it started working instantly (after an Apache reload).
I'm not sure why this needs to be explicitly enabled. On other servers it used to work as soon as I enabled the mod with a2enmod (maybe with Apache 2.2, but I can't find a clear pattern)

Old question but here's what I learned:
Press F12 in your browser (I'm using Chrome) and go to the "Network" tab and look for the javascript that's not getting cached. Look for the header information there (via a "Headers" tab, for example) and look at the "content-type" in the response header information.
In my case it was "application/javascript", which I hadn't defined specifically in my .htaccess. Once I added that line:
ExpiresByType application/javascript "access plus 2419200 seconds"
Then javascript was getting cached as expected.

Related

Getting and Verifying Image Headers Expires

I am working on SEO and need to verify that Image Headers Expires is working. Both modules for expires and headers are installed and enabled.
Any ideas?
The .htaccess file has this in it
<IfModule mod_expires.c>
ExpiresByType application/javascript "access plus 2 days"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 2 days"
</IfModule>
I have added this to both the wordpress/ directory and the wordpress/wp-content/ directory.
And yet the SEO tool is saying "Your server is not using expires header for your images."
to test using curl I have done
Date: Sun, 15 Jan 2023 04:31:01 GMT
Server: Apache
Location: https://www.jaycocioservices.com/about
Content-Type: text/html; charset=iso-8859-1
You are missing the ExpiresActive directive to enable the generation of the relevant Expires and Cache-Control headers.
You don't need the <IfModule> wrapper - this is only going to mask the error if mod_expires is not installed.
You don't need the ExpiresByType image/jpg ... directive since the correct mime-type is image/jpeg, which you already have in the directive that follows.
You don't need to repeat these directives in both the /wordpress and /wordpress/wp-content directories. Placing these directives in the root .htaccess file should be sufficient and naturally applies to all subdirectories.
Also consider setting an ExpiresDefault directive for all other mime-types.
For example:
ExpiresActive On
ExpiresByType application/javascript "access plus 2 days"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 2 days"
ExpiresDefault "access plus 1 day"
to test using curl I have done
Date: Sun, 15 Jan 2023 04:31:01 GMT
Server: Apache
Location: https://www.jaycocioservices.com/about
Content-Type: text/html; charset=iso-8859-1
That looks like a redirect response (due to the presence of the Location header), which perhaps should not be cached anyway (or left to the browser default in the case of a 301). Make sure you are requesting the canonical URL to test.
This (/about text/html) is also for a request not covered by your existing mod_expires directives. You need to be requesting an image, CSS or JS file.

'expire' and 'file_cache' mods are 'enabled' but will not show in mod list nor works in htaccess

It is a Ubunto 16.04 64bit LAMP server. I have enabled Cache header with
sudo a2enmod file_cache
and expire header with
sudo a2enmod expires
Then I restarted Apache server with
service apache2 restart
but those mods are not showing in
/usr/sbin/apache2 -l
Output:
Compiled in modules:
core.c
mod_so.c
mod_watchdog.c
http_core.c
mod_log_config.c
mod_logio.c
mod_version.c
mod_unixd.c
and lavarage caching in .htaccess is not working either.
Tried this expire headers,
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 30 seconds"
ExpiresByType text/html "access plus 15 days"
ExpiresByType image/gif "access plus 1 months"
ExpiresByType image/jpg "access plus 1 months"
ExpiresByType image/jpeg "access plus 1 months"
ExpiresByType image/png "access plus 1 months"
ExpiresByType text/js "access plus 1 months"
ExpiresByType text/javascript "access plus 1 months"
</IfModule>
The response header is
Response headers (317 B)
Cache-Control
max-age=1296000
CF-RAY
43dff56b31ff70b6-SIN
Connection
keep-alive
Content-Encoding
gzip
Content-Type
text/html; charset=UTF-8
Date
Sat, 21 Jul 2018 19:08:52 GMT
Expires
Sun, 05 Aug 2018 19:11:07 GMT
Server
cloudflare
Transfer-Encoding
chunked
Vary
Accept-Encoding
Edit: Cloudflare(free plan) is enabled with default settings.
Actually Cloudflare cache your website content, try flushing cache from cloudflare admin panel if you are using cloudflare as proxy.

Last modification date of web page unknown

I would like to check the age of the document in the webpage, but it does not show! Here is the result of a telnet to the server:
telnet av.hostoi.com 80
Connected to av.hostoi.com. HEAD / HTTP/1.0
HTTP/1.1 200 OK Date: Tue, 23 Oct 2012 16:55:40 GMT
Server: Apache
X-Powered-By: PHP/5.2.17
Connection: close
Content-Type: text/html
Connection closed by foreign host.
On another server the following 2 lines are also included which are not present above:
Last-Modified: Fri, 17 Jun 2011 11:17:45 GMT
ETag: "2ce392-b1-4a5e688eae840"
So I searched the Internet and as far as I could figure out, there should be a configuration in Apache to set headers on and etag on in htaccess. But I couldn't find any place that shows me that.
Here are the loaded modules in Apache if it would help:
core mod_authn_file mod_authn_default mod_authz_host mod_authz_groupfile mod_authz_user mod_authz_default mod_auth_basic mod_include mod_filter mod_log_config mod_env mod_expires mod_headers mod_setenvif mod_version prefork http_core mod_mime mod_status mod_autoindex mod_asis mod_info mod_vhost_alias mod_negotiation mod_dir mod_actions mod_alias mod_rewrite mod_so mod_php5 mod_ruid2
As far as I read mod_header must be enabled which seems to be the case.
Any help on this?
edit:
tried the proposed solution:
put a .htaccess file in / folder even though there is a file named do not upload here.
contents of .htaccess:
<code>
# Do not remove this line, otherwise mod_rewrite rules will stop working
RewriteBase /
Options -Indexes
SSILastModified on
<IfModule mod_expires.c>
FileETag MTime Size
ExpiresActive on
ExpiresDefault "access plus 10 days"
ExpiresByType application/javascript "access plus 1 week"
ExpiresByType application/x-javascript "access plus 1 week"
ExpiresByType application/x-shockwave-flash "access plus 1 week"
ExpiresByType text/css "access plus 1 week"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/x-icon "access plus 6 month"
ExpiresByType image/ico "access plus 6 month"
</IfModule>
</code>
i put this file in public_html folder and in the sub folder nod_update3 where the file update.ver exists.
then i execute the script that checks the age of the document like so:
./check_http -H av.hostoi.com -u /nod_update3/update.ver -M 2d
HTTP CRITICAL: HTTP/1.1 200 OK - Document modification date unknown - 26316 bytes in 0,159 second response time |time=0,158965s;;;0,000000 size=26316B;;;0
as you can see no modification date is shown even though on the ftp client it shows it was last modified 25.10.2012
i tried the check on another file in the same folder like so:
./check_http -H av.hostoi.com -u /nod_update3/em000_32_l0.nup -M 2d
HTTP CRITICAL: HTTP/1.1 200 OK - Last modified 13,5 days ago - 56472 bytes in 1,059 second response time |time=1,059014s;;;0,000000 size=56472B;;;0
srvmon plugins #
as you can see the date modification is known. so why the problem with ver file?
the file can be checked in this url:
http://av.hostoi.com/nod_update3//update.ver
The problem is that you have caching of static content enabled on first server, and on second one that is not the case.
Please take a look in apache main configuration file,virtual host or .htacess on second server
if you have something similar to:
<IfModule mod_expires.c>
FileETag MTime Size
ExpiresActive on
<filesMatch "\.ver$">
ExpiresDefault "modification plus 2 week"
</filesMatch>
</IfModule>
Also you need to enable apache module mod_expires.
Hope this helps!
By tracking back to the source code of Apache, we can see the root cause of this misconfiguration is that the semantics enabled by "Xbithack Full" implicitly overwrite the semantics enabled by "SSILastModified On".
if (conf->lastmodified > 0) {
... {
ap_update_mtime(r, r->finfo.mtime);
ap_set_last_modified(r);}}
else if (((conf->xbithack == XBITHACK_FULL ||
(conf->xbithack == XBITHACK_UNSET &&
DEFAULT_XBITHACK == XBITHACK_FULL))
...)) {
ap_update_mtime(r, r->finfo.mtime);
ap_set_last_modified(r);
}
One possible solution here is to replace "SSILastModified on" with "Xbithack Full".

CloudFront image cache-control headers

1- Is this a valid cache control header:
Cache-Control: max-age=86400, s-maxage=3600
2- I am trying to set cache control headers for objects served from S3 through CloudFront. The images don't often change, but sometimes can. Does this seem like a good cache control for this? CloudFront should re-validate every 60 minutes, but the user will cache for a full day. (I'm less worried about an individual user and more worried about continuing to serve the stale image to new users).
3- Are there other headers I should use? (ie. proxy-revalidate)
Its not horrendously easy to change these settings on S3 objects so I'm trying to get it right the first time. Thanks.
I just made it working with both
Access-control-Max-Age (Set in S3 CORs setting)
Cache-control
expires
In theory and from AWS S3 / Cloudfront doc, only 1. will works. In practice, it takes both.
Keith
Here's what I got to work:
Cache-Control: max-age=29030400, public
Expires: Wed, 30 Dec 2015 18:00:00 GMT
In theory, you only need one or the other. But this whole browser caching thing with S3 and CloudFront has been a big pain in my backside, so I like to keep them both in there. And I also put the following in my .htaccess file:
# BEGIN Caching
Header set Cache-Control "max-age=29030400, public"
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 year"
ExpiresByType text/css "access plus 1 year"
ExpiresByType text/plain "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType application/x-javascript "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType application/x-icon "access plus 1 year"
</IfModule>
# END Caching

Set-Cookie and Expires headers differ

I'm trying to enable Expires headers for images as recommended by YSlow. I'm sure I had this working before but now when I check YSlow it says they are not being cached.
For my .htaccess, I have tried:
ExpiresActive on
ExpiresDefault A0
<FilesMatch "\.(gif|ico|jpg|png)$">
ExpiresDefault A29030400
Header append Cache-Control "public"
</FilesMatch>
and
ExpiresActive on
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 month"
http://www.seoconsultants.com/tools/headers.asp outputs the following for one of my images:
HTTP Status Code: HTTP/1.1 200 OK
Date: Mon, 05 Oct 2009 20:12:04 GMT
Server: Apache/2.0.63 (Unix) mod_ssl/2.0.63 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4 PHP/5.2.8
X-Powered-By: PHP/5.2.8
Set-Cookie: PHPSESSID=5d11f4d8aa37ceee6605786e59ff4f0f; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: lastlogin=1254773024; expires=Mon, 02-Nov-2009 20:12:04 GMT
Connection: close
Content-Type: image/jpeg
The Set-Cookie part looks correct but the Expires header is not. How do I set Expires correctly and why do they differ? I have double checked that mod_expires and mod_headers are enabled.
From the Set-Cookie header, it looks like this is part of a PHP session. PHP automatically disables caching after a session_start().
You can modify this behavior by changing session.cache_limiter in your php.ini. See the PHP manual page for the various settings.
Alternatively, you could try using set instead of append to override the headers in your .htaccess.