Fighting client-side caching in Django

前端 未结 7 884
傲寒
傲寒 2020-11-27 13:18

I\'m using the render_to_response shortcut and don\'t want to craft a specific Response object to add additional headers to prevent client-side caching.

I\'d like to

相关标签:
7条回答
  • 2020-11-27 13:58

    I was scratching my head when the three magic meta didn't work in Firefox and 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',
        ...
    
    0 讨论(0)
  • 2020-11-27 13:59

    Regarding the Google Chrome browser (Version 34.0.1847.116 m) and the other browsers, I found that only the @cache_control decorator is working. I use Django 1.6.2.

    Use it like this:

    @cache_control(max_age=0, no_cache=True, no_store=True, must_revalidate=True)
    def view(request):
        ...
    
    0 讨论(0)
  • 2020-11-27 14:05

    You can achieve this using the cache_control decorator. Example from the documentation:

    from django.views.decorators.cache import never_cache
    
    @never_cache
    def myview(request):
       # ...
    
    0 讨论(0)
  • 2020-11-27 14:06

    Here is a rewrite of @Meilo's answer for 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
    
    0 讨论(0)
  • 2020-11-27 14:09

    This approach (slight modification of L. De Leo's solution) with a custom middleware has worked well for me as a site wide solution:

    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
    

    This makes use of add_never_cache_headers.


    If you want to combine this with UpdateCacheMiddleware and FetchFromCacheMiddleware, to enable server-side caching while disabling client-side caching, you need to add DisableClientSideCachingMiddleware before everything else, like this:

    MIDDLEWARE_CLASSES = (
        'custom.middleware.DisableClientSideCachingMiddleware',
        'django.middleware.cache.UpdateCacheMiddleware',
        # ... all other middleware ...
        'django.middleware.cache.FetchFromCacheMiddleware',
    )
    
    0 讨论(0)
  • 2020-11-27 14:10

    Actually writing my own middleware was easy enough:

    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
    

    Still doesn't really behave like i wanted but so neither does the @never_cache decorator

    0 讨论(0)
提交回复
热议问题