web-dev-qa-db-fra.com

NodeJS/express: Cache et code d'état 304

Lorsque je recharge un site Web créé avec express, j'obtiens une page vierge avec Safari (pas avec Chrome) car le serveur NodeJS m'envoie un code d'état 304.

Comment résoudre ce problème?

Bien sûr, cela pourrait aussi être juste un problème de Safari, mais en réalité cela fonctionne très bien sur tous les autres sites Web, il doit donc en être de même sur mon serveur NodeJS.

Pour générer les pages, j'utilise Jade avec res.render.

Mise à jour: Il semble que ce problème se produise car Safari envoie 'cache-control': 'max-age=0' lors du rechargement.

Mise à jour 2: J'ai maintenant une solution de contournement, mais y a-t-il une meilleure solution? Contournement:

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…
}

Mise à jour 3: La partie de code complète est donc actuellement:

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);
    }
}
71
h345k34cr

La solution la plus simple:

app.disable('etag');

Solution alternative ici si vous voulez plus de contrôle:

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

70
blented

Comme vous l'avez dit, Safari envoie Cache-Control: max-age = 0 lors du rechargement. Express (ou plus précisément sa dépendance, node-fresh) considère le cache comme obsolète lors de la réception d'en-têtes Cache-Control: no-cache, mais il n'en est pas de même pour Cache-Control: max-age = 0. D'après ce que je peux dire, cela devrait probablement l'être. Mais je ne suis pas un expert en cache.

Le correctif consiste à changer (ce qui est actuellement) la ligne 37 de node-fresh/index.js de

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

à

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

J'ai créé un nœud en mode node-fresh et exprès d'inclure ce correctif dans le package.json de mon projet via npm, vous pouvez en faire de même. Voici mes fourches, par exemple:

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

La branche safari-reload-fix est basée sur la balise 3.4.7.

3
James P. Javery

J'avais le même problème dans Safari et Chrome (les seuls que j'ai testés), mais je viens de faire quelque chose qui semble fonctionner. Au moins, je n'ai pas été en mesure de reproduire le problème depuis que j'ai ajouté la solution. Ce que j'ai fait a été d'ajouter une métabalise à l'en-tête avec un timstamp généré. Ça ne semble pas juste mais c'est simple :)

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

Mise à jour P.S Pour autant que je sache, le problème disparaît lorsque je supprime mon proxy de noeud (par proxy, je veux dire à la fois le module express.vhost et le module de proxy http), ce qui est étrange ...

2
user907567

Essayez d’utiliser la navigation privée dans Safari ou de supprimer l’ensemble de votre cache/cookie.

J'ai eu des problèmes similaires avec l'utilisation de chrome lorsque le navigateur pensait que le site Web était dans son cache mais n'en avait pas.

La partie de la requête http qui fait répondre le serveur par 304 est le etag. On dirait que Safari envoie le bon etag sans avoir le cache correspondant.

1
sbugert

Vieille question, je sais. Désactiver la fonction de cache n’est pas nécessaire et n’est pas le meilleur moyen de gérer le problème. En désactivant la fonction de cache, le serveur doit travailler plus fort et générer plus de trafic. De plus, le navigateur et l'appareil doivent travailler plus fort, en particulier sur les appareils mobiles, cela pourrait poser problème. 

La page vide peut être facilement résolue en utilisant la touche Maj + bouton de rechargement du navigateur. 

La page vide peut être le résultat de:

  • un bug dans votre code 
  • pendant le test, vous avez servi une page vide (vous ne pouvez pas vous rappeler) qui est mise en cache par le navigateur 
  • un bogue dans Safari (le cas échéant , signalez-le à Apple et n'essayez pas de le réparer vous-même)

Essayez d’abord la touche Maj du clavier + le bouton de rechargement pour voir si le problème persiste et relisez votre code.

0
Codebeat