how do i cache specific files html / css? - javascript

how do i cache specific files in html ?
i have tried
meta http-equiv="cache-control" content="private" max-age="604800"
but when i click "audit" using google chrome inspect element
its giving me
Leverage browser caching (4)
The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers:
some.css
some.js
The following resources are explicitly non-cacheable. Consider making them cacheable if possible:
some.html
some-hosted.html
how do i cache em ?

Your syntax is invalid.
<meta http-equiv="cache-control" content="max-age=604800;private" />
Mind you this won't work for CSS/JS or anything else that isn't a HTML file. In those cases you need to set real HTTP headers server-side (which is usually done using webserver settings or via dynamic server-side languages like PHP, .Net, Coldfusion, etc...).

The best way of doing this is to server your files through some kind of server side mechanism that attaches the right cache control headers to the http response.

Related

How to serve static gzipped javascript files in lighttpd?

Background:
I have a small RaspberyPi-like server on Armbian (20.11.6) (precisely - on Odroid XU4).
I use lighttpd to serve pages (including Home Assistant and some statistics and graphs with chartjs).
(the example file here is Chart.bundle.min.js.gz)
Issue:
There seems to be a growing amount of javascript files, which become larger than the htmls and the data itself (some numbers for power/gas consumption etc.). I am used to use mod_compress, mod_deflate etc on servers (to compress files on the fly), but this would kill the Odroid (or unnecessarily load CPU and the pitiful SD card for caching).
Idea:
Now, the idea is, just to compress the javascript (and other static (like css)) files and serve it as static gzip file, which any modern browser can/should handle.
Solution 0:
I just compressed the files, and hoped that the browser will understand it...
(Clearly the link was packed in the script html tag, so if the browser would get that gz is a gzip... it should maybe work).
It did not ;)
Solution 1:
I enabled mod_compress (a suggested on multiple pages) and and tried to serve static js.gz file.
https://www.drupal.org/project/javascript_aggregator/issues/601540
https://www.cyberciti.biz/tips/lighttpd-mod_compress-gzip-compression-tutorial.html
Without success (browser takes it as binary gzip, and not as application/javascript type).
(some pages suggested enabling mod_deflate, but it does not seem to exist)
Solution 2:
(mod_compress kept on) I did the above, and started fiddling with the Content-Type, Content-Encoding in the HTML (in the script html tag). This did not work at all, as the Content-Type can be somehow influenced in HTML, but it seems that the Content-Encoding can not.
https://www.geeksforgeeks.org/http-headers-content-type/
(I do not install php (which could do it) to save memory, sd card lifetime etc.).
Solution 3:
I added "Content-Encoding" => "gzip" line to the 10-simple-vhost.conf default configuration file in the setenv.add-response-header. This looked as a dirty crazy move, but I wanted to check if the browser accepts my js.gz file... It did not.
And furthermore nothing loaded at all.
Question:
What would be an easy way to do it ? (without php).
Maybe something like htaccess in Apache ?
EDIT 1:
It seems that nginx can do it out-of-the-box:
Serve static gzip files using node.js
http://nginx.org/en/docs/http/ngx_http_gzip_static_module.html
I am also digging into the headers story in lighttpd:
https://community.splunk.com/t5/Security/How-to-Disable-http-response-gzip-encoding/m-p/64396
EDIT 2:
Yes... after some thinking, I got to the idea that it seems that this file could be cached for a long time anyway, so maybe I should not care so much :)
Your solution (below) to set the response header is a workable one for your situation.
However, I would recommend using lighttpd mod_deflate with deflate.cache-dir (lighttpd 1.4.56 and later)
When configured properly, lighttpd will serve gzipped Content-Encoding to clients which support the compression, and lighttpd will serve plain content to clients which do not support the compression. lighttpd will compress each file as it is served and will save the compressed file in deflate.cache-dir so that lighttpd does not have to re-compress the file the next time the file is requested. lighttpd will detect if the original file has changed and will re-compress it into the cache the next time the file is requested.
It seems that I was writing the question so long, that I was near to the solution.
I created an module file 12-static_gzip.conf, with following content:
$HTTP["url"] =~ ".gz" {
setenv.add-response-header = (
"Content-Encoding" => "gzip"
)
}
I have not found any similar trick for lighttpd, so I applied here a similar solution which I would use for Apache. Expected behavior was, that it will just respond the Content-Encoding header for the gz files, without using php or any additional modules... and it works !!!
The mod_compress module or any other of this kind is disabled and no other changes are needed.
Clearly, the http negotiation is more complex, so I am not sure if this will work for all browsers, but it surely work very nicely for Chrome.
I am also planning to create some ESP32 web servers, where drive and memory are even more critical, so I will try to apply similar solution.
Nevertheless, the questions still hold...
is there a better/cleaner solution ?
Are there some caveats to be expected ? Browser compatibility etc. ?

Why does adding " rel='stylesheet' " stop local css file from loading in browser?

I have a problem where I'm trying to to load a local css file (e.g. theme.css) as follows:
<link rel="stylesheet" type="text/css" href="theme.css">
I am using Chrome (but I've tried in Microsoft Edge, as well), and the file won't load. It will be stuck as (pending) forever. If I remove the "rel" property than the file will load properly, without any problems.
I have been a developer for a few years now (although I haven't been working this low level for some time) and I don't remember ever encountering this problem.
I understand this might seem a bit inane for some, but I am very curious why this happens.
EDIT:
I am using Nodejs to return an using this code:
var server = http.createServer(function(req, res) {
var page = url.parse(req.url).pathname;
if (page == '/') {
index = 0;
fs.readFile('index.html', function(err, data) {
res.writeHead(200, {"Content-Type": "text/html"});
res.write(data);
res.end();
I think I am starting to understand the problem. Is it because I am using Nodejs to read an html file, and that file cannot dynamically return css files locally specified inside?
I've realised what the problem was. Because I am using node.js to serve the server (in this case localhost) files, I needed to serve specifically the files in my requests (such as having a route to script.js and theme.css). I thought that simply returning the html that contains the files (locally) would suffice, since opening index.html would return the js and css files without any problem. I am not sure why rel="stylesheet" would affect whether the file could be loaded anyways.
Thank you for the help.
Judging from your comment the problem appears to be related to accessing a non https resource from https.
See this link about referer policy: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
Importantly the section on integration with CSS:
CSS can fetch resources referenced from stylesheets. These resources
are following a referrer policy as well.
External CSS stylesheets use the default policy
(no-referrer-when-downgrade) unless it's overwritten via an HTTP
header that is set for a CSS stylesheet specifically.
For inline styles or styles created from APIs like HTMLElement.style,
the owner document's referrer policy is used.
My guess is that when the rel attribute is set then it uses the default policy, but when it isn't then it uses the documents policy. This is a curious interaction and I'm not sure it's supposed to work like that.
EDIT: I can see from your update that you aren't using HTTPS, so I'm not sure why this would be relevant. The message in your comment definitely referenced the referrer policy, and I saw this and made a logical conclusion.
Now I'm not sure. For now I'm going to leave this answer and then I may delete it if another, correct, idea comes up

How to save scripts, images and css files into browser cache?

I have been trying to enable Caching for my web-page. I find-out so much post related to Caching static file in browser cache, but i did't get success.
I try for both server side or client side code for it:
SERVER SIDE
I tried to put code for set-up a "Cache-Control" header on server side page-load(write code in C#) :
DateTime dt = DateTime.Now.AddMinutes(30);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
HttpContext.Current.Response.Cache.SetExpires(dt);
HttpContext.Current.Response.Cache.SetMaxAge(new TimeSpan(dt.Ticks - DateTime.Now.Ticks));
Reference
CLIENT SIDE
In javascript after some googling i find a "Preloading images" technique , but applying this code also not give me correct solution of storing file into cache.
Reference
HTML META TAGS
Added following tags in my page header:
<meta http-equiv="Cache-control" content="private"/>
<meta http-equiv="EXPIRES" content="Wed, 16 oct 2013 11:12:01 GMT"/>
did't get success.
Reference
Can any one tell me what i am doing wrong here?
And any one suggest me for perfect solution/full tutorial for enabling cache to store static files into browser cache.
Thanks in advance....!!!!
First i think you have confused caching with preloading images.
If what you really need is caching, check your browser whether caching is disabled.Because scripts,images and css are cached defaultly by browser.
Next how did you check whether those are cached?
You could use "cache-manifest" which uses AppCache of the browser.
It allows you to run your website offline also.
Head to http://diveintohtml5.info/offline.html for more information.
Hope it helps!!

Force download through markup or JS

Lets assume I have a file on a CDN (Cloud Files from Rackspace) and a static html page with a link to that file. Is there any way I can force download this file (to prevent it from opening in the browser -- for mp3s for example)?
We could make our server read the file and set the corresponding header to:
header("Content-Type: application/force-download")
but we have about 5 million downloads per month so we would rather let the CDN take care of that.
Any ideas?
There’s no way to do this in HTML or JavaScript. There is now! (Ish. See #BruceAldrige’s answer below.)
The HTTP Content-Disposition header is what tells browsers to download the files, and that’s sent by the server. You have to configure the CDN to send that header with whichever files you want to browser to download instead of display.
Unhelpfully, I’m entirely unfamiliar with Rackspace’s Cloud Files service, so I don’t know if they allow this, nor how to do it. Just found a page from December 2009 that suggests not thought, sadly:
Cloud Files cannot serve a file with the 'Content-Disposition: attachment' HTTP header. Therefore, a download link that would work perfectly in any other service may result in the browser rendering the file directly. This was confirmed by Rackspace engineers. :-(
http://drupal.org/node/656714
I know that you can with Amazon’s CloudFront service, as it’s backed by S3 (see e.g. http://blog.cloudberrylab.com/2009/06/how-to-set-custom-http-headers-for.html)
You can use the download attribute:
<a href="http..." download></a>
https://stackoverflow.com/a/11024735/21460
However, it’s not currently supported by Safari (7) or IE (11).
Yes, you can do this through the cloudfiles API. Using the method stream allows you to stream the contents of files in - setting your own headers etc.
A crazy idea: download via XMLHttpRequest and serve a data: URL with the content type you want? :P

Problems with Cache in Firefox when i upload my app to web server

Can anyone help? I have been designing a site using Javascript but the rest of the html content is static ie. images etc
When i load my page in Firefox i have to clear the cache..
I remember a long time ago there was something you could add to the html to force a reload.
My question is, is this a good thing? I presume it caches for a reason i.e to cahce images etc.. But this causes my pages not to refresh
And how to do it?
Really appreciate any feedback
If you want only the js to be loaded afresh everytime, and leave everything else to load from cache, you can add a version number to the js include line like so:
<script src="scripts.js?v=5643" type="text/javascript"></script>
Change the version number (?v=num) part each time you change the js file. This forces the browser to get the js file from the server.
Note: Your actual file name will be the same - scripts.js
For disabling cache for all files, if you're using apache, put this in your httpd.conf
<Directory "/home/website/cgi-bin/">
Header Set Cache-Control "max-age=0, no-store"
</Directory>
You can also put a meta tag on your html like so:
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
More info on this here
For web pages you can how the page is cached in the HTTP Header. You should look at Expires if you have a particular date for the cache to expire or Cache-Control for dynamic expiration based on when the page was requested. Here's a pretty good tutorial that covers how cache works and covers set up on the major web servers.
Try pressing Control + F5 when you load your page in FireFox-- this should clear your browser's cache of the page and reload cleanly for you.

Categories