在Django中对抗客户端caching
我正在使用render_to_response快捷方式,并不想制作特定的Response对象来添加额外的标头以防止客户端caching。
我想有一个回应,其中包含:
- Pragma:no-cache
- caching控制:无caching
- caching控制:必须重新validation
还有浏览器希望解释为避免caching的指令的所有其他漂亮的方法。
有没有caching中间件或类似的东西,可以用最小的代码入侵做的伎俩?
你可以使用cache_control装饰器来达到这个目的。 来自文档的示例:
from django.views.decorators.cache import never_cache @never_cache def myview(request): # ...
这种方法(L. De Leo解决scheme的微小修改)和定制的中间件对于我来说是一个很好的解决scheme:
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
结合使用,要在禁用客户端caching的同时启用服务器端caching,则需要先添加DisableClientSideCachingMiddleware
,如下所示:
MIDDLEWARE_CLASSES = ( 'custom.middleware.DisableClientSideCachingMiddleware', 'django.middleware.cache.UpdateCacheMiddleware', # ... all other middleware ... 'django.middleware.cache.FetchFromCacheMiddleware', )
补充现有的答案。 这里是一个装饰器,添加额外的头来禁用caching:
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装饰器也没有
关于谷歌浏览器(版本34.0.1847.116米)和其他浏览器,我发现只有@cache_control
装饰工作。 我使用Django 1.6.2。
像这样使用它:
@cache_control(max_age=0, no_cache=True, no_store=True, must_revalidate=True) def view(request): ...