Борьба с кэшированием на стороне клиента в Django
Я использую ярлык render_to_response и не хочу создавать конкретный объект ответа для добавления дополнительных заголовков, чтобы предотвратить кэширование на стороне клиента.
Я хотел бы иметь ответ, который содержит:
- Pragma: no-cache
- Cache-control: no-cache
- Cache-control: must-revalidate
и все другие изящные способы, которые браузеры будут, надеюсь, интерпретировать как директивы, чтобы избежать кэширование.
есть ли промежуточное программное обеспечение без кэша или что-то подобное, что может сделать трюк с минимальным вторжением кода?
7 ответов:
вы можете достичь этого с помощью декоратора 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.
если вы хотите объединить это с
UpdateCacheMiddlewareиFetchFromCacheMiddleware, чтобы включить кэширование на стороне сервера при отключении кэширования на стороне клиента, вам нужно добавить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.116 m) и других браузеров, я обнаружил, что только
@cache_controlдекоратор работает. Я использую Django 1.6.2.используйте его так:
@cache_control(max_age=0, no_cache=True, no_store=True, must_revalidate=True) def view(request): ...
вот переписать @Meilo это для Django 1.10+:
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
я чесал голову, когда три магии
metaне работал в Firefox и 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" />видимо, это может произойти потому, что некоторые браузеры будут игнорировать стороне клиента
meta, поэтому он должен быть обработан на сервере.я попробовал все ответы из этого поста для моего класса на основе представлений (
django==1.11.6). Но, ссылаясь на ответы от @Lorenzo и @Zags, я решил написать промежуточное программное обеспечение, которое я считаю простым.так что добавление к другим хорошим отвечает,
# 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', ...
Comments