NodeJS / express: Кеш-пам'ять і код стану 304


92

Коли я перезавантажую веб-сайт, створений за допомогою express, я отримую порожню сторінку в Safari (не в Chrome), оскільки сервер NodeJS надсилає мені код стану 304.

Як це вирішити?

Звичайно, це також може бути просто проблемою Safari, але насправді це прекрасно працює на всіх інших веб-сайтах, тому це також має бути проблемою на моєму сервері NodeJS.

Для створення сторінок я використовую Jade with res.render.

Оновлення: Здається, ця проблема виникає, оскільки Safari надсилає 'cache-control': 'max-age=0'при перезавантаженні.

Оновлення 2: Зараз у мене є обхідний шлях, але чи є краще рішення? Вирішення проблеми:

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

Оновлення 3: Отже, повна частина коду на даний момент:

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

1
304 - це не проблема. Це просто означає, що ваша відповідь не змінена, і ваш браузер переходить у кеш для отримання ресурсу. Чи можете ви розмістити відповідний код, в якому відбувається аномалія.
Акшат Джіван Шарма

3
так, насправді він не модифікований, але Safari очищає кеш на CMD + R (перезавантажити), а сервер лише повідомляє, що він не змінився.
h345k34cr

Як порожня сторінка пов’язана з кодом стану 304? Вузол також надсилає 304 в інші браузери.
user568109

2
Це пов’язано, оскільки з 304 тіло не надсилається, і браузер використовує його кеш, але оскільки кешу немає, ви отримуєте порожню сторінку
h345k34cr

1
@AkshatJiwanSharma Будь-яка програма розроблена, щоб точно відповідати контракту власника продукту. Власником товару є той, хто володіє кодом і платить гроші, а не якась організація, яка пише документи, про які нікому не цікаво. Якщо в контракті вказано "200", то абсолютно будь-який статус, який не дорівнює "200", є помилкою. Коли є помилка, Я ПОВИНЕН переписувати код, поки все не стане так, як очікувалося. W3C не мають права голосу в цьому питанні.
Герман

Відповіді:


107

Найпростіше рішення:

app.disable('etag');

Альтернативне рішення тут, якщо ви хочете отримати більше контролю:

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


2
Не могли б ви пояснити "найпростіший спосіб вирішення проблеми" чи дати посилання на те, як це впливає?
Самуель Мендес,

1
@ SamuelMéndez це в основному відключає кешування, у вікі на etag є багато хорошої інформації en.wikipedia.org/wiki/HTTP_ETag
видалено

Працював у мене :)
Naveen Kumar V

3

Як ви вже сказали, Safari надсилає Cache-Control: max-age=0при перезавантаженні. Express (або, більш конкретно, залежність Express, node-fresh) вважає кеш застарілим під час отримання Cache-Control: no-cacheзаголовків, але не робить те саме для Cache-Control: max-age=0. З того, що я можу сказати, це, мабуть, повинно бути. Але я не фахівець з кешування.

Виправлено змінити (те, що зараз) рядок 37 node-fresh/index.jsз

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

до

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

Я розгалужив node-fresh та express, щоб включити це виправлення до мого проекту package.jsonчерез npm, ви могли б зробити те саме. Ось мої вилки, наприклад:

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

Гілка safari-reload-fix заснована на тегу 3.4.7.


Чудова робота! Я бачу, що express 3.5.1 включає ваше виправлення через node-fresh 0.2.2.
Клафу

Насправді, я помиляюся, ваше виправлення було скасовано і насправді не досягло 0,2.2. Досі немає свіжого / експрес-виправлення.
Клафу

2

У мене була та сама проблема в Safari та Chrome (єдині, які я протестував), але я просто зробив щось, що, здається, працює, принаймні, я не зміг відтворити проблему, оскільки додав рішення. Що я зробив, це додав метатег до заголовка із сформованою тимчасовою міткою. Не здається правильно, але це просто :)

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

Оновлення PS Наскільки я можу зрозуміти, проблема зникає, коли я видаляю проксі-вузол (під проксі я маю на увазі і express.vhost, і http-проксі-модуль), що дивно ...


Я також використовую проксі Apache, це може бути проблемою. Моїм обхідним шляхом було просто вимкнути кешування для тематичних сайтів із заголовками http.
h345k34cr

Вимкнення кешу через заголовки - це, безумовно, шлях. Спочатку це не спрацьовувало у мене, але зараз працює. Іншими словами, я, мабуть, десь помилився вперше :)
user907567

1

Спробуйте скористатися приватним переглядом у Safari або видалити весь кеш / файли cookie.

У мене були подібні проблеми з використанням chrome, коли браузер вважав, що веб-сайт є в кеші, але насправді його не було.

Частина запиту http, яка змушує сервер відповісти 304, є етапом. Здається, Safari надсилає правильний етап, не маючи відповідного кешу.


це працює для мене, коли я намагався видалити весь кеш, дякую
Юттант Сувансірі

0

Старе питання, я знаю. Вимкнення кеш-пам'яті не потрібно і не найкращий спосіб вирішити проблему. Вимикаючи кеш-пам'ять, сервер повинен працювати інтенсивніше і генерує більше трафіку. Крім того, браузер і пристрій повинні працювати інтенсивніше, особливо на мобільних пристроях це може бути проблемою.

Порожню сторінку легко вирішити за допомогою клавіші Shift + кнопки перезавантаження в браузері.

Порожня сторінка може бути результатом:

  • помилка у вашому коді
  • під час тестування ви подали порожню сторінку (ви не пам’ятаєте), яка кешована браузером
  • помилка в Safari (якщо так, повідомте про це Apple і не намагайтеся виправити це самостійно)

Спробуйте спочатку клавішу клавіатури Shift + кнопку перезавантаження та перевірте, чи проблема все ще існує, і перегляньте свій код.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.