NodeJS / express : 캐시 및 304 상태 코드


92

Express로 만든 웹 사이트를 다시로드하면 NodeJS 서버가 304 상태 코드를 보내므로 Safari (Chrome이 아님)에서 빈 페이지가 나타납니다.

이것을 해결하는 방법?

물론 이것은 Safari의 문제 일 수도 있지만 실제로는 다른 모든 웹 사이트에서 잘 작동하므로 NodeJS 서버에서도 문제가 될 것입니다.

페이지를 생성하기 위해 저는 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는 문제가되지 않습니다. 단순히 응답이 수정되지 않고 브라우저가 리소스를 가져 오기 위해 캐시로 전환됨을 의미합니다. 이상이 발생하는 관련 코드를 게시 할 수 있습니까?
Akshat Jiwan Sharma 2013

3
예, 실제로 수정되지는 않았지만 Safari는 CMD + R (다시로드)에서 캐시를 비우고 서버는 변경되지 않았다고 만 말합니다.
h345k34cr 2013 년

빈 페이지는 304 상태 코드와 어떤 관련이 있습니까? 노드는 또한 304를 다른 브라우저로 보냅니다.
user568109

2
그것은 304과 몸이 전송되지 않기 때문에 관련 및 브라우저 캐시를 사용하지만 캐시가 없기 때문에, 당신은 빈 페이지를 얻을 수있다
h345k34cr

1
@AkshatJiwanSharma 모든 프로그램은 제품 소유자의 계약을 정확히 충족하도록 개발되었습니다. 제품 소유자는 아무도 신경 쓰지 않는 문서를 작성하는 조직이 아니라 코드를 소유하고 돈을 지불하는 사람입니다. 계약서에 "200"이 표시되면 "200"이 아닌 모든 상태는 버그입니다. 버그가있을 때 모든 것이 예상대로 될 때까지 코드를 다시 작성해야합니다. W3C는이 문제에 대해 발언권이 없습니다.
Gherman

답변:


109

가장 쉬운 솔루션 :

app.disable('etag');

더 많은 제어가 필요한 경우 여기에 대체 솔루션 :

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


3
"가장 쉬운 해결책"을 설명하거나 이것이 어떤 영향을 미치는지에 대한 참조를 제공 할 수 있습니까?
Samuel Méndez 2018

2
@ SamuelMéndez은 기본적으로 캐싱을 비활성화, ETAG에 위키 좋은 정보를 많이 가지고 en.wikipedia.org/wiki/HTTP_ETag
blented

나를 위해 일했습니다 :)
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;

나는 노드 신선한 포크와 내 프로젝트의에서이 수정을 포함하는 표현 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를 통한 수정 사항이 포함되어 있습니다.
Clafou

사실, 틀 렸습니다. 수정 사항이 되돌려졌고 실제로 0.2.2로 변경되지 않았습니다. 여전히 신선하거나 명시적인 수정이 없습니다.
Clafou 2014

2

Safari와 Chrome (내가 테스트 한 유일한 문제)에서 동일한 문제가 발생했지만 작동하는 것처럼 보이는 작업을 수행했습니다. 적어도 솔루션을 추가 한 이후로 문제를 재현 할 수 없었습니다. 내가 한 일은 생성 된 timstamp와 함께 헤더에 메타 태그를 추가하는 것입니다. 옳지 않은 것 같지만 간단합니다 :)

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

PS 업데이트 내가 말할 수있는 한, 내 노드 프록시를 제거하면 문제가 사라집니다 (프록시는 express.vhost 및 http-proxy 모듈을 의미합니다). 이상합니다 ...


또한 Apache 프록시를 사용하는데 이것이 문제가 될 수 있습니다. 내 해결 방법은 http 헤더가있는 콘텐츠 사이트에 대한 캐싱을 비활성화하는 것입니다.
h345k34cr

헤더를 통해 캐시를 비활성화하는 것이 확실히 방법입니다. 처음에는 작동하지 않았지만 지금은 작동합니다. 즉, 어딘가에서 처음으로 실수를
했음에 틀림 없다

1

Safari에서 시크릿 브라우징을 사용하거나 전체 캐시 / 쿠키를 삭제 해보십시오.

브라우저가 캐시에 웹 사이트가 있다고 생각했지만 실제로는 그렇지 않은 경우 크롬을 사용하여 유사한 문제가 발생했습니다.

서버가 304에 응답하도록 만드는 http 요청의 일부는 etag입니다. Safari가 해당 캐시없이 올바른 etag를 보내는 것 같습니다.


내가, 전체 캐시를 삭제 감사하려고 나를 위해 작동하는지
Yuttanant Suwansiri을

0

오래된 질문입니다. 캐시 기능을 비활성화하는 것은 필요하지 않으며 문제를 관리하는 가장 좋은 방법이 아닙니다. 캐시 기능을 비활성화하면 서버가 더 열심히 작업하고 더 많은 트래픽을 생성해야합니다. 또한 브라우저와 장치가 더 열심히 작동해야합니다. 특히 모바일 장치에서는 이것이 문제가 될 수 있습니다.

빈 페이지는 브라우저에서 Shift 키 + 다시로드 버튼을 사용하여 쉽게 해결할 수 있습니다.

빈 페이지는 다음과 같은 결과 일 수 있습니다.

  • 코드의 버그
  • 테스트하는 동안 브라우저에 캐시 된 빈 페이지 (기억할 수 없음)를 제공했습니다.
  • Safari의 버그 (그렇다면 Apple에보고하고 직접 고치려고하지 마십시오)

먼저 Shift 키보드 키 + 다시로드 버튼을 시도하고 문제가 여전히 존재하는지 확인하고 코드를 검토합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.