Nginx+Django环境下如何配置生效的Cache-Control: no-store?
首先先修正你配置里的一个明显错误:locallibrary.conf中监听8080的server块完全无效且会导致请求循环——Waitress已经在8080端口运行,这个server又把请求反向代理回8080,会造成死循环,直接删掉这个块即可。
下面提供两种可行方案,根据你的需求选择:
方案一:直接在Nginx层面彻底禁用缓存
如果要全局禁止所有内容被缓存,直接修改监听80的cache-proxy server配置,移除所有缓存相关指令并添加Cache-Control头部:
# cache-proxy server { listen 80; location / { proxy_pass http://127.0.0.1:8080/; # 移除或注释掉所有proxy_cache相关配置 # proxy_cache_key "$host$request_uri:u:$cookie_user"; # proxy_cache_valid any 10s; # proxy_cache cache; # 添加no-store头部,always参数确保所有响应都携带该头部(包括错误响应) add_header Cache-Control no-store always; # 可选:添加Pragma兼容旧浏览器 add_header Pragma no-cache always; } }
修改完成后重启Nginx,此时Nginx不会再往proxy_cache_path指定的目录写入缓存,同时所有响应都会携带Cache-Control: no-store头部。
方案二:由Django控制缓存策略,Nginx配合生效
如果需要更灵活的控制(比如部分页面缓存、部分禁止),可以让Django返回Cache-Control: no-store头部,再配置Nginx根据该头部决定是否缓存:
步骤1:在Django中设置响应头部
方式一:全局生效(通过中间件)
在你的Django项目中创建一个中间件文件(比如middleware.py):
from django.utils.deprecation import MiddlewareMixin class NoCacheMiddleware(MiddlewareMixin): def process_response(self, request, response): # 给所有响应添加no-store头部 response['Cache-Control'] = 'no-store' response['Pragma'] = 'no-cache' return response
然后在settings.py的MIDDLEWARE列表中添加这个中间件(建议放在中间件列表的末尾):
MIDDLEWARE = [ # 其他已有的中间件... 'locallibrary.middleware.NoCacheMiddleware', ]
方式二:仅在特定视图生效
如果只需要给某个视图禁止缓存,直接在视图函数中设置:
from django.http import HttpResponse def my_view(request): response = HttpResponse("自定义内容") response['Cache-Control'] = 'no-store' return response
步骤2:修改Nginx配置,根据后端头部决定是否缓存
调整监听80的cache-proxy server配置,添加proxy_no_cache和proxy_cache_bypass指令,让Nginx识别后端返回的no-store头部并跳过缓存:
# cache-proxy server { listen 80; location / { proxy_pass http://127.0.0.1:8080/; proxy_cache_key "$host$request_uri:u:$cookie_user"; proxy_cache_valid any 10s; proxy_cache cache; # 当后端返回的Cache-Control包含no-store时,不缓存且不使用缓存内容 proxy_no_cache $http_cache_control; proxy_cache_bypass $http_cache_control; # 确保后端的Cache-Control头部能透传给客户端 proxy_pass_header Cache-Control; } }
修改完成后重启Nginx和Django服务,此时Nginx会根据Django返回的Cache-Control头部决定是否缓存内容,同时客户端会收到no-store头部。
内容的提问来源于stack exchange,提问作者Kenion

