NodeJS / express: cache status code and 304

When I reload a website created using express delivery, I get a blank page with Safari (not Chrome), because the NodeJS server sends me a status code of 304.

How to solve this?

Of course, this might also just be a Safari problem, but it actually works fine on all other sites, so this is also a problem on my NodeJS server.

To generate pages, I use Jade with res.render .

Update: It seems this problem occurs because Safari sends 'cache-control': 'max-age=0' on reboot.

Update 2: I now have a workaround, but is there a better solution? Workaround:

 app.get('/:language(' + content.languageSelector + ')/:page', function (req, res) { // Disable caching for content files res.header("Cache-Control", "no-cache, no-store, must-revalidate"); res.header("Pragma", "no-cache"); res.header("Expires", 0); // rendering stuff hereโ€ฆ } 

Update 3: So, the full piece of code is currently:

 app.get('/:language(' + content.languageSelector + ')/:page', pageHandle); function pageHandle (req, res) { var language = req.params.language; var thisPage = content.getPage(req.params.page, language); if (thisPage) { // Disable caching for content files res.header("Cache-Control", "no-cache, no-store, must-revalidate"); res.header("Pragma", "no-cache"); res.header("Expires", 0); res.render(thisPage.file + '_' + language, { thisPage : thisPage, language: language, languages: content.languages, navigation: content.navigation, footerNavigation: content.footerNavigation, currentYear: new Date().getFullYear() }); } else { error404Handling(req, res); } } 
+78
safari caching express
Sep 15 '13 at 10:24
source share
6 answers

The simplest solution:

 app.disable('etag'); 

An alternative solution is here if you want more control:

http://vlasenko.org/2011/10/12/expressconnect-static-set-last-modified-to-now-to-avoid-304-not-modified/

+78
May 16 '14 at 23:48
source share

As you said, Safari sends Cache-Control: max-age = 0 on reboot. Express (or, more specifically, the Express, node-fresh dependency) considers the cache to be out of date when Cache-Control: no-cache headers are received, but it does not do the same for Cache-Control: max-age = 0. From of what I can say, it probably should be. But I'm not a caching specialist.

The fix is โ€‹โ€‹to change (currently) line 37 from node-fresh / index.js from

 if (cc && cc.indexOf('no-cache') !== -1) return false; 

to

 if (cc && (cc.indexOf('no-cache') !== -1 || cc.indexOf('max-age=0') !== -1)) return false; 

I unlocked node-fresh and express to include this patch in my package.json project via npm , you can do the same. Here are my forks, for example:

https://github.com/stratusdata/node-fresh https://github.com/stratusdata/express#safari-reload-fix

The safari-reload-fix branch is based on the 3.4.7 tag.

+3
Jan 10 '14 at 1:43
source share

I had the same problem in Safari and Chrome (only the ones I tested), but I just did something that seems to work, at least I was not able to reproduce the problem since I added a solution. What I did was add a meta tag to the header with the generated timestamp. Doesn't seem right, but it's simple :)

 <meta name="304workaround" content="2013-10-24 21:17:23"> 

PS Update As far as I can tell, the problem disappears when I delete the node proxy (by proxy, I mean both express.vhost and http-proxy module), which is strange ...

+2
Oct 24 '13 at 19:26
source share

Try using private browsing in Safari or delete all cache / cookies.

I had some similar problems using chrome when the browser thought it had a website in cache, but actually it wasnโ€™t.

The part of the HTTP request that makes the server respond to 304 is this. It seems like Safari is sending the correct etag without the corresponding cache.

+1
Sep 15 '13 at 20:07 on
source share

Old question, I know. Disabling the caching function is not required and is not the best way to solve the problem. By disabling the caching function, the server should work more and generate more traffic. In addition, the browser and the device should work more, especially on mobile devices, this can be a problem.

A blank page can be easily resolved using the Shift key + reload in the browser.

A blank page may be the result of:

  • error in your code
  • during testing, you served a blank page (which you donโ€™t remember) that is cached by the browser
  • bug in Safari (if so, please report it to Apple and do not try to fix it yourself)

First, try pressing the Shift key + reset button and see if the problem persists and review your code.

0
Sep 10 '18 at 12:55
source share

This ... This is the easiest way ...

function force200Responses(req, res, next) { req.headers['if-none-match'] = 'no-match-for-this'; next(); }

app.use(force200Responses)

The future of me please.

0
Dec 18 '18 at 9:57
source share



All Articles