programing

Django에서 클라이언트 측 캐싱과 싸우기

nasanasas 2020. 11. 13. 08:22
반응형

Django에서 클라이언트 측 캐싱과 싸우기


render_to_response 바로 가기를 사용하고 있으며 클라이언트 측 캐싱을 방지하기 위해 헤더를 추가하기 위해 특정 Response 개체를 만들고 싶지 않습니다.

다음을 포함하는 응답을 받고 싶습니다.

  • Pragma : 캐시 없음
  • 캐시 제어 : 캐시 없음
  • 캐시 제어 : 반드시 재확인

그리고 브라우저가 캐싱을 피하기위한 지시어로 해석하는 다른 모든 멋진 방법.

최소한의 코드 침입으로 트릭을 수행 할 수있는 캐시가없는 미들웨어 또는 이와 유사한 것이 있습니까?


cache_control 데코레이터를 사용하여이를 수행 할 수 있습니다. 문서의:

from django.views.decorators.cache import never_cache

@never_cache
def myview(request):
   # ...

맞춤형 미들웨어를 사용한이 접근 방식 (L. De Leo 솔루션의 약간 수정)은 사이트 전체 솔루션으로 저에게 잘 맞았습니다.

from django.utils.cache import add_never_cache_headers

class DisableClientSideCachingMiddleware(object):
    def process_response(self, request, response):
        add_never_cache_headers(response)
        return response

이것은 add_never_cache_headers.


당신이이 결합하려는 경우 UpdateCacheMiddlewareFetchFromCacheMiddleware클라이언트 측 캐싱을 사용하지 않도록하면서 서버 측 캐싱을 사용하려면, 당신은 추가해야 DisableClientSideCachingMiddleware다음과 같이 다른 모든 전에 :

MIDDLEWARE_CLASSES = (
    'custom.middleware.DisableClientSideCachingMiddleware',
    'django.middleware.cache.UpdateCacheMiddleware',
    # ... all other middleware ...
    'django.middleware.cache.FetchFromCacheMiddleware',
)

기존 답변을 보완합니다. 다음은 캐싱을 비활성화하기 위해 헤더를 추가하는 데코레이터입니다.

from django.views.decorators.cache import patch_cache_control
from functools import wraps

def never_ever_cache(decorated_function):
    """Like Django @never_cache but sets more valid cache disabling headers.

    @never_cache only sets Cache-Control:max-age=0 which is not
    enough. For example, with max-axe=0 Firefox returns cached results
    of GET calls when it is restarted.
    """
    @wraps(decorated_function)
    def wrapper(*args, **kwargs):
        response = decorated_function(*args, **kwargs)
        patch_cache_control(
            response, no_cache=True, no_store=True, must_revalidate=True,
            max_age=0)
        return response
    return wrapper

다음과 같이 사용할 수 있습니다.

class SomeView(View):
    @method_decorator(never_ever_cache)
    def get(self, request):
        return HttpResponse('Hello')

실제로 내 미들웨어를 작성하는 것은 충분히 쉬웠습니다.

from django.http import HttpResponse


class NoCacheMiddleware(object):

    def process_response(self, request, response):

        response['Pragma'] = 'no-cache'
        response['Cache-Control'] = 'no-cache must-revalidate proxy-revalidate'

        return response

여전히 내가 원했던 것처럼 작동하지 않지만 @never_cache 데코레이터도 마찬가지입니다.


Google Chrome 브라우저 (버전 34.0.1847.116m) 및 기타 브라우저와 관련하여 @cache_control데코레이터 작동 하는 것으로 나타났습니다 . Django 1.6.2를 사용합니다.

다음과 같이 사용하십시오.

@cache_control(max_age=0, no_cache=True, no_store=True, must_revalidate=True)
def view(request):
    ...

Django 1.10+에 대한 @Meilo의 답변다시 작성했습니다 .

from django.utils.cache import add_never_cache_headers

class DisableClientCachingMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        add_never_cache_headers(response)
        return response

metaFirefox와 Safari에서 세 가지 마법 이 작동하지 않을 때 머리를 긁적 입니다.

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

Apparently it can happen because some browsers will ignore the client side meta, so it should be handled at server side.

I tried all the answers from this post for my class based views (django==1.11.6). But referring to answers from @Lorenzo and @Zags, I decided to write a middleware which I think is a simple one.

So adding to other good answers,

# middleware.py
class DisableBrowserCacheMiddleware(object):

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response['Pragma'] = 'no-cache'
        response['Cache-Control'] = 'no-cache, no-store, must-revalidate'
        response['Expires'] = '0'
        return response

# settings.py
MIDDLEWARE = [
    'myapp.middleware.DisableBrowserCacheMiddleware',
    ...

참고URL : https://stackoverflow.com/questions/2095520/fighting-client-side-caching-in-django

반응형