Rails에서 브라우저 페이지 캐싱을 방지하는 방법


151

우분투-> 아파치-> Phusion Passenger-> Rails 2.3

내 사이트의 주요 부분은 클릭에 반응합니다. 따라서 링크를 클릭하면 목적지로 이동하여 즉시 페이지를 재생성합니다.

그러나 뒤로 버튼을 누르면 새 페이지가 표시되지 않습니다. 불행히도 수동으로 새로 고치지 않으면 표시되지 않습니다. 브라우저가 캐시하고있는 것 같습니다. 브라우저가 페이지를 캐시하지 않도록하고 싶습니다.

별도로, 내가 내 모든 고정 자산 먼 미래의 만료 날짜를 설정합니다.

이것을 해결하는 가장 좋은 방법은 무엇입니까? Rails에서이 문제를 해결해야합니까? 아파치? 자바 스크립트?

모든 도움을 주셔서 감사합니다, Jason


아아. 이러한 제안 중 어느 것도 내가 원하는 행동을 강요하지 않았습니다.

아마도 자바 스크립트 답변이 있습니까? 레일에 주석에 타임 스탬프를 쓰도록하고 시간이 5 초 (또는 작동하는 것이 무엇이든)인지 확인하기 위해 자바 스크립트를 검사하도록 할 수 있습니다. 그렇다면 괜찮지 만 그렇지 않으면 페이지를 다시로드 하시겠습니까?

이것이 효과가 있다고 생각합니까?

모든 도움을 주셔서 감사합니다

제이슨

답변:


335

- 마지막으로이 알아 낸 http://blog.serendeputy.com/posts/how-to-prevent-browsers-from-caching-a-page-in-rails/ 의를application_controller.rb

레일 후 5 :

class ApplicationController < ActionController::Base

  before_action :set_cache_headers

  private

  def set_cache_headers
    response.headers["Cache-Control"] = "no-cache, no-store"
    response.headers["Pragma"] = "no-cache"
    response.headers["Expires"] = "Mon, 01 Jan 1990 00:00:00 GMT"
  end
end

Rails 4 및 이전 버전 :

class ApplicationController < ActionController::Base

  before_filter :set_cache_headers

  private

  def set_cache_headers
    response.headers["Cache-Control"] = "no-cache, no-store"
    response.headers["Pragma"] = "no-cache"
    response.headers["Expires"] = "Mon, 01 Jan 1990 00:00:00 GMT"
  end
end

3
"if request.xhr에 싸여 있어야합니까?" 그래서 그것은 아약스 새로 고침에서만 설정되지만 일반 페이지는 그렇지 않습니다?
MintDeparture

3
Cache-Control: no-store브라우저가 HTTP 1.1을 준수하는 한 실제로 필요합니다 . 캐시로 저장 될 수있는 어떤 섹션 14.9.2
gaqzi

28
1990 년 1 월 1 일은 월요일이었습니다!
Jan Hettich

2
그것은 나를 위해 작동하지 않습니다 application_controller.rb에 동일한 코드를 추가했으며 로그 아웃 후 뒤로 버튼으로 마지막 페이지를 볼 수 있습니다. 내가 잘못한 곳을 알려주세요.
Thorin

1
이것도 rails 앱에서 JS와 CSS를 캐시하지 않습니까? 각 요청에 대해 서버에서 JS와 CSS가로드됩니까?
furiabhavesh

14

3
expires_nowno-cache헤더 만 보냅니다 . 브라우저에 따라 충분하지 않을 수 있습니다. (예를 들어 파이어 폭스는 원하는 no-store비 HTTPS 연결을 위해 : developer.mozilla.org/en/docs/Using_Firefox_1.5_caching )
다니엘 Rikowski

1
합의에 따라이 솔루션은 Rails 5.2 및 Chrome 77에서 테스트 한 유효한 솔루션이 아닙니다 no-store. 또한 필요합니다.
AndrewSouthpaw

3

나는이 라인을 컨트롤러에서 약간의 성공으로 사용했습니다. Safari 및 Internet Explorer에서 작동하지만 Firefox에서 작동하는 것을 보지 못했습니다.

response.headers["Expires"] = "#{1.year.ago}"

두 번째로, 다음과 같은 레일 도우미 메소드를 사용하는 경우

stylesheet_link_tag

기본 설정을 웹 서버에 그대로두면 자산이 일반적으로 잘 캐시됩니다.


3
1.year.ago불필요한 오버 헤드입니다. 과거처럼 임의의 시간을 선택하십시오Fri, 01 Jan 1990 00:00:00 GMT
Archonic

6
@Archonic 1990 년 1 월 1 일은 월요일이었습니다!
Thomas R. Koll

1

더 깔끔한 방법은 랙 미들웨어를 작성하는 것입니다. 랙 미들웨어는 일부 논리 (예 : application / xml mime-type)에 따라 Cache-Control 헤더를 변경합니다. 또는 추악하지만 여전히 작동하는 접근 방식의 경우 ActionDispatch :: Response :: DEFAULT_CACHE_CONTROL 상수를 'no-cache'로 변경할 수 있습니다. 물론 컨트롤러 및 / 또는 작업 세분성이 필요한 경우 컨트롤러에서이 작업을 수행하는 것이 좋습니다.


1

참고 사항 : 캐시를 조건부로 지울 수 없습니다 (예 : 사용자가 이미있는 경우 before_filter에만 호출하는 reset_cache경우). 당신은 할 필요가 무조건 브라우저가이 시간, 그것은 다시로드 할 필요가있는 경우 새로운 요청을 그냥 볼 수 있도록하지 않기 때문에이 마지막 시간이 필요하지 않은 경우에도, 캐시를 지 웁니다.

예:

before_filter :reset_cache, if: :user_completed_demographics?

브라우저는 뒤로 버튼에서 원래 캐시 헤더를 사용하기 때문에 사용자가 방문한 후 다시 방문하는 것을 막을 수 없습니다.

before_filter :reset_cache

그러나 첫 번째 요청에서 브라우저가 no-cache, no-store, ...페이지를 가져 와서 향후 페이지로드에 적용 하기 때문에 페이지를 새로 고치고 캐시를 삭제 한 후 분명히 작동 합니다.


0

no_cache_control 보석.

침투 테스트 (BURP, Detectify 등)를 통과하기 위해 모든 응답에 대해이 작업을 수행해야하는 경우 모든 응답에 다음 헤더를 추가하기 위해이 Gem on Rails 4+를 설치할 수 있습니다.

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: -1

매력처럼 작동하며 실제로 인증을 요구하는 안전한 HTTPS 웹 응용 프로그램을 사용하기에 가장 적합한 방법입니다.

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