Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to set Cache-Control Header in nodeJS server response #5697

Closed
jcamara-dsg opened this issue Jun 6, 2024 · 7 comments
Closed

Unable to set Cache-Control Header in nodeJS server response #5697

jcamara-dsg opened this issue Jun 6, 2024 · 7 comments

Comments

@jcamara-dsg
Copy link

jcamara-dsg commented Jun 6, 2024

I'm trying to return a Cache-Control header in the response from a nodeJS server. Following is my server file:

/*
 * Express server
 */
const app = express();

/*
 * Health Checks
 */
app.get('/healthcheck', (req, res) => {
	res.set('Cache-Control', 'max-age=300, must-revalidate')
	res.json({
		health: 'OK'
	});
});

Screenshot of response headers:
image

I'm able to set any custom headers but not Cache-Control. There are no middlewares that are running. Any ideas on what I could be doing wrong in this case?

Thanks in advance

@jcamara-dsg jcamara-dsg changed the title Unable to set Cache-Control Header in server Unable to set Cache-Control Header in nodeJS server response Jun 6, 2024
@danizavtz
Copy link

I couldn't reproduce this problem, I created a brand new project only to try to reproduce this problem, link here I only copied and pasted the code sample shared in this issue and it worked as expected setting the header.

To check if header cache-control is present I just used curl with argument -I (vowel letter "I" in caps lock):

curl -I http://localhost:3000/healthcheck

This is the output:

X-Powered-By: Express
Cache-Control: max-age=300, must-revalidate
Content-Type: application/json; charset=utf-8
Content-Length: 15
ETag: W/"f-zkBsEbirArjpKvVbiSV3QbfXWrg"
Date: Fri, 07 Jun 2024 13:28:52 GMT
Connection: keep-alive
Keep-Alive: timeout=5

Please let me know if I miss some step.

@jcamara-dsg
Copy link
Author

I figured my problem out. The cache-control header seems to be stripped out in development mode. Is this intended or documented anywhere?

Whenever I build for production and serve locally, I'm able to see the cache control header.

@danizavtz
Copy link

danizavtz commented Jun 7, 2024

Also couldn't reproduce this problem. Just updated the project with an environment variable.

Now the project has two methods to start.

npm start

this has a global NODE_ENV exported variable with value production as documented, you can check the variables exported in package.json.

And another:

npm run dev

this has a global NODE_ENV exported variable with value development.

In both methods the response is working as expected, setting the header cache-control. I receive the same header I put in response.

I just used curl to check the response.

Just start the application in with npm start, using terminal, run curl: curl -I http://localhost:3000/healthcheck, check response. Stop application.


Just start the application in with `npm run dev`, using terminal, run curl: `curl -I http://localhost:3000/healthcheck`, check response. Stop application.

Both ways (production and developement) it is working.

I just updated (made a new commit) in the same project I shared in first answer. As a collateral effect (by the way I exported the variable) now it work only in unix compatible environments. (if you use Windows it will fail and you will have to figure out a way to export the variable).

So the behavior you are receiving I could't reproduce.

@danizavtz
Copy link

Putting the problem aside, I think you have a conceptual problem here.

I know it must be a proof of concept but ... in my opinion health check responses should never be cached and should be as ephemeral and atomic as possible. So your tool that reads the health check can act to prevent disruption of your service.

@jcamara-dsg
Copy link
Author

@danizavtz Correct, this is just a proof of concept. I have an actual route that renders html server side and returns the html. I was not seeing the Cache-Control headers at all so I wanted to whittle it down a simple example to see what could be causing the issue. After I built the app in production mode, I was able to see the expected Cache-Control header.

@IamLizu
Copy link
Member

IamLizu commented Jul 18, 2024

@jcamara-dsg what is your express and node version? I am on node v20.10.0 and express ^4.19.2,

const express = require("express")
require("dotenv").config();

const app = express();

app.get('/', (req, res) => {
	res.set('Cache-Control', 'max-age=300, must-revalidate')
	res.json({
		message: 'Hello World',
		env: process.env.NODE_ENV
	});
});

app.listen(3000)

I have added the env in the json response so it gets printed in the browser. Then start the server with,

export NODE_ENV=development && node index.js

I believe you will see similar response in the browser,

{
    "message": "Hello World",
    "env": "development"
}

You can try changing the NODE_ENV to test whether its actually changing or not. And if we look using curl or the browser network tab, I believe we will see something similar to,

HTTP/1.1 200 OK
X-Powered-By: Express
Cache-Control: max-age=300, must-revalidate
Content-Type: application/json; charset=utf-8
Content-Length: 45
ETag: W/"2d-tw3UuNH/7L4DyTVSsRzaBIX2crU"
Date: Thu, 18 Jul 2024 09:44:34 GMT
Connection: keep-alive
Keep-Alive: timeout=5

@coltonehrman
Copy link

@jcamara-dsg I can't reproduce this either. I have an example+test setup here https://github.com/coltonehrman/bag-of-tools/blob/main/examples/express/cache-control-header/headers.test.ts if you are interested.

@IamLizu IamLizu converted this issue into discussion #5848 Aug 23, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

5 participants