I have a working flow that serves a page of HTML in response to a GET request. The HTML references some images that I have in a 'images' directory in the location configured in settings.js (/home/username/.node-red/node-red-static/). This all works as expected.
Except....I've been trying to preload images as I have a background image that changes periodically and want it to transition smoothly rather than line-by-line, etc, as sometimes happens, and discover that the content (image) is not being cached when preloaded and an inspection of the headers shows the following (example related to one of the images, but actually they all show the same):
Cache-Control: public, max-age=0
I've found a few articles about setting response headers using code in a function node (eg Setting headers with "HTTP Response" node) but this would appear to be relevant only for content served by a node and not served from the static folders.
Is anyone able to help with setting the Cache-Control header for static content?
Thanks again...I assume that code gets added to settings.js?
And then the screen you captured appears in the editor somewhere?
Apologies if I'm missing something obvious but I'm not really understanding. Will attempt to add it to settings.js and see whether next steps become obvious.
Thanks Steve-mcl....this looks like it ties in with GogoVega's suggestions - will do some experimenting as this is an area I've had no previous experience in or even tinkered with. Thanks again
The image is an example of the http node.
Here you have to do it in the settings file by combining Steve's message and mine
httpStatic: [
{
path: '/home/username/.node-red/node-red-static/',
root: '/static/',
middleware: function (req, res, next) {
const ext = path.extname(req.url);
// Check if the request is for JPG or PNG images
if (ext === '.jpg' || ext === '.png') {
// Set Cache-Control header for images
res.setHeader('Cache-Control', 'public, max-age=86400');
}
// Continue to the next middleware
next();
}
}
]
Thanks again everyone, for your time and effort, I clearly have some reading to do - all I appear to be able to do so far is stop Node-RED from starting at all.
I've reverted everything so I have a working setup but clearly need to do some reading so will do that and continue to experiment.
I believe that the correct method is to use req.get('Content-Type') which should return the mime type of the requested resource. This should be, at least in part, independent of the file name and particularly the file extension. It also doesn't need to require the path library.
OK, I think the above is out of date (though probably still works). You should use:
with the following in settings.js I get the required Cache-Control header BUT I get it for everything (which is actually fine for my purposes but now that I've seen what you were all trying to do above I want to crack it for the images alone and it seems to be the condition that is breaking it)
httpStatic: [
{
path: '/home/username/.node-red/node-red-static/',
root: '/static/',
middleware: function (req, res, next) {
// Set Cache-Control header for images
res.setHeader('Cache-Control', 'public, max-age=86400');
// Continue to the next middleware
next();
}
}
],
Unfortunately, when I add in the condition using GogoVega's "endsWith" or "path.extname" examples Node-RED will not restart. I am still working on understanding enough about TotallyInformation's suggestion to write something based on that but am working on it.
Well I don't know what I was doing above because the following is now working but wasn't before, and I can't reproduce the issue - must have been a stray comma or similar
httpStatic: [
{
path: '/home/username/.node-red/node-red-static/',
root: '/static/',
middleware: function (req, res, next) {
if (req.url.endsWith('.jpg') || req.url.endsWith('.png')) {
// Set Cache-Control header for images
res.setHeader('Cache-Control', 'public, max-age=86400');
}
// Continue to the next middleware
next();
}
}
],
and is caching only JPGs and PNGs from the static folder.
Thanks again all, very much, for your input - working solution and learned something new too!
(Still haven't understood enough about req.is() to get that working, sorry TotallyInformation - maybe I'll try again later)
Thanks, yes I understood that from the information in the page he linked. I think the reason it isn't working for me is that I don't know what the 'type' should be - for html it would clearly be 'text/html' but for a JPG I've tried 'image/jpg' and 'image' but neither work.
What should the content type be in the request header for my JPGs? Or, how can I find that? I found the Cache-Control info by inspecting the response headers in Google Chrome's "inspect" feature but am not seeing anything for content-type in the request headers in the same tool.