304 / If-modified-since / HEAD 요청을 방지하기위한 헤더


31

내용을 캐시 한 후 서버에 대한 모든 요청을 완전히 중지하기 위해 어떤 헤더를 보내야합니까?

대기 시간이 매우 긴 서버 (Sigh, VMWare)가 있으므로 HEAD서버에 요청을 보내는 데에도 40ms가 걸립니다.

현재 이들은 송수신되는 헤더입니다.

첫 번째 요청

고객이 보낸다.

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Pragma: no-cache, no-cache, no-cache
Cache-Control: no-cache, no-cache, no-cache

서버가 응답합니다.

HTTP/1.1 200 OK
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:51:51 GMT
Content-Type: text/plain
Vary: Accept-Encoding
Last-Modified: Tue, 31 Jan 2012 10:45:11 GMT
Content-Length: 14
Expires: Thu, 31 Jan 2013 14:51:51 GMT
Cache-Control: max-age=31536000

따라서 앞으로 365 일로 설정된 Cache-ControlExpires헤더를 보냅니다 . 불행히도 두 번째 새로 고침에서는 If-Modified-Since헤더로 객체를 다시 요청합니다 .

두 번째 요청

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
If-Modified-Since: Tue, 31 Jan 2012 10:45:11 GMT
Cache-Control: max-age=0

응답;

HTTP/1.1 304 Not Modified
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:58:00 GMT
Vary: Accept-Encoding
Expires: Thu, 31 Jan 2013 14:58:00 GMT
Cache-Control: max-age=31536000

불행히도 오래된 프록시 소프트웨어로 인해 Keep-Alive응용 프로그램 앞에을 (를) 사용 하거나 다른 서버 / 프록시를 사용할 수 없습니다 . 또한 서버 성능을 향상시키고 네트워크 대기 시간을 줄일 수 없습니다. 301 요청을 제거하기 위해 보낼 수있는 헤더를 알아 내려고 노력했습니다. ETags를 사용해 보았지만 아무런 차이가 없지만 여전히 If-modified-since헤더를 보냅니다 . 또한 Last-Modified헤더를 제거하려고 시도했지만 캐싱없이 표준 GET 요청이 발생합니다 (로그를 확인하고 서버는 여전히 요청을 수신합니다).

클라이언트는 Firefox (주로), IE 7, 8 및 (일부) 9, Chrome 및 Safari의 혼합이지만이 동작은 테스트 된 모든 브라우저에서 나타나는 것으로 보입니다.

TL; DR;

끔찍한 네트워크, 클라이언트에게 캐시를 확인하기 위해 절대로If-modified-since 서버에 요청을 보내지 않고Expires 헤더가 충족 될 때까지 콘텐츠를 캐시로 유지 하지 말라고 보내려면 어떤 헤더를 보내야 합니까?

아마도 분명한 것이 누락되었지만 시도하는 모든 결과가 동일한 결과를 얻는 것처럼 보입니다.

우리는 응용 프로그램 서버 앞에 NGINX 서버가 있으므로 원하는대로 헤더를 추가 / 제거 할 수 있습니다. 프록시는 Keep-Alive를 지원하지 않으며 부실한 네트워크 성능을 향상시킬 수있는 방법이 없습니다. 끔찍한 소프트웨어 디자인으로 인해 웹 응용 프로그램은 각 페이지로드 (예 : 엔터프라이즈 소프트웨어 짜증)에 +100 개의 리소스를 객체 당 ~ 40-50ms의 대기 시간으로로드합니다.


1
흠, 이상하다. Expires 및 max age 헤더를 보내면 이미지가 더 이상 요청되지 않습니다. 편집 : 그런데, JPG를 다음과 같이 보내는 것은 text/plain무엇입니까?
DisgruntledGoat

1
@DisgruntledGoat Ahh, .jpg 파일이 실제로 텍스트 문서가 아닌 이미지라고 가정했습니다. 내 세계에 오신 것을 환영합니다 =) (실제로 테스트를 위해 'Hello World'를 포함하는 텍스트 파일입니다. 소프트웨어는 유형에 관계없이 순차적으로 모든 파일의 이름을 IMG_xxxx.jpg로 바꿉니다. Cool huh?)
Smudge

http 요청 헤더를 설정하기 위해 무엇을 사용 했습니까?
barlop

답변:


25

사용자 에이전트가 사용자에게 전송하기로 결정한 헤더는 실제로 제어 할 수 없습니다. 문제의 파일이 브라우저의 캐시에 있고 새 버전을 확인해야한다고 결정하면 파일이 업데이트됩니다. 에 따르면 이 글 이 브라우저는 수정 한 이후 경우-사용 요청합니다 상황은 다음과 같습니다 :

  • 캐시 된 항목에 만료 날짜가 없으며 브라우저 세션에서 처음으로 내용에 액세스하고 있습니다.
  • 캐시 된 항목에 만료 날짜가 있지만 만료되었습니다
  • 사용자가 새로 고침 단추를 클릭하거나 F5를 눌러 페이지 업데이트를 요청했습니다.

따라서 캐싱을 테스트하기 위해 페이지를 다시로드하는 경우 브라우저가 이미지를 다시 요청하므로 작동하지 않습니다. 링크를 클릭 한 다음 다른 페이지를 첫 페이지로 다시 연결하십시오. 사용자가 정기적으로 페이지를 다시로드하는 경우이를 방지하기 위해 사이트 / 앱 구조를 재고해야합니다.

캐시 컨트롤 헤더에 "public"을 추가하는 것이 도움이 될 수 있습니다 Cache-Control: public, max-age=31536000. 또한 최근 1 년 이상의 만료 날짜가 유효하지 않다는 것을 알게되었습니다 . 만료 날짜는 정확히 1 년이므로 며칠 또는 몇 주 정도 줄이면 파일이 브라우저 캐시에 유지되고 삭제되지 않습니다.


흥미롭게도, 만료일을 60 일로 줄이고 공개 플래그를 추가하고 어떻게되는지 살펴 보겠습니다. 이것은 F5가 아닌 링크 클릭에서 발생하는 것 같습니다 (Firebug 및 서버 로그에 따름)
Smudge

기술적으로 HTTP / 1.1 사양 은 "서버가 만료 날짜를 1 년 이상 보내서는 안된다"고 말하고 (아마도 만료되기 전에 너무 긴 시간이기 때문에) 앞으로 "약 1 년"이 적절한 만료라고합니다. 만료되지 않은 콘텐츠를 보낼 시간입니다.
Ilmari Karonen

1
장난 조금 후에, 나는 365d 만료가 영향을 미치는되지 체결 한 우리의 내가 안전을 위해 아래로 떨어했습니다 그러나 클라이언트, 보이는 Cache-Control: public,...이 특정 상황의 핵심이었다.
Smudge

"공개"헤더가 불필요한 왕복을 수정 했습니까? 나는 그것을 시도했지만 성공하지 못했습니다 ...
phtrivier

2
대답이 명확하지 않은 경우 브라우저에서 페이지를 다시로드하면 파일이 다시 요청됩니다 . 링크를 클릭하여 페이지를 열면 브라우저가 해당 캐시를 사용합니다.
DisgruntledGoat


3

나는 같은 문제가 있었고 요청은 서버가 304상태 에 응답하기 위해 서버에 확실히 도달하고 있습니다 . 304를 일부 C #을 통해 보내고 서버에 도달 했는지 확인하십시오.

나는 단지 Cache-Control: private설정했다. 아니오 max-age및 아니오 Expires예상대로 작동했습니다. If-Modified-Since내가 기대하는 것과 비교하여 값을 테스트하고 304빈 응답 본문을 포함 하여 서버를 공격하십시오. 그렇지 않으면 200응답 본문을 가득 채 웁니다.

클라이언트에서 Expires헤더를 설정 하면 원하는 결과를 200 - (from cache)얻었으며 HTTP 요청이 서버에 도달하지 않았습니다.

그러나 .. 그 설정이 발견 BOTH max-age= & Expires되지 전송에 브라우저가 발생할 수 있습니다 If-Modified-Since헤더 전혀 캐시하지 값이 일치하지 않는 경우 .

캐싱 문제가 있고 다른 헤더를 조합하여 사용하는 경우 알아야 할 사항입니다.


1

주제가 조금 있지만 도움이 될 수 있습니다. 캐시 된 콘텐츠 요청에 대한 또 다른 개선 사항은 sessionStorage에 캐시하여 서버에 캐시를 확인하고 304를 수신 할 필요가 없도록하는 것입니다. google을 찾아 콘솔을 열고 sessionStorage를 작성하십시오. sessionStorage를 사용하여 CSS 또는 DOM을 캐싱하고 있음을 알 수 있습니다. ofc, 오래된 IE 브라우저에서는 사용할 수 없습니다.


0

소스 코드를 살펴보고 다른 페이지로 전환 할 META REFRESH가 없는지 확인하십시오. 대신 sendRedirect와 같은 것을 사용하십시오. 내 설정에서 META REFRESH는 IE에서는 304를 생성하지만 Chrome에서는 생성하지 않습니다. sendRedirect는 어느 브라우저에서나 이것을 생성하지 않습니다.

<meta http-equiv="refresh" content="0;URL='nextpage'" />    

vs

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