我在Django中间件中设置了一些非caching头来控制xhr请求的caching。 主要是因为IE严重caching了Ajax请求。
class NeverCacheXhrMiddleware(object): """ sets no-cache headers for all xhr requests xhr requests must send the HTTP_X_REQUESTED_WITH header to be identified correctly as a xhr request using .is_ajax() see: http://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers """ def process_response(self, request, response): if request.is_ajax(): #add_never_cache_headers(response) #patch_cache_control(response, no_cache=True) response['Cache-Control'] = 'no-cache, no-store, must-revalidate' response['Pragma'] = 'no-cache' response['Expires'] = '0' return response
当我在开发环境中仅使用Gunicorn部署我的应用程序时,这工作正常。 在生产环境中,我们也在Gunicorn前面运行NGINX,看来NGINX正在覆盖Django设置的头文件。
看这个截图看看如何改变标题:
DEV Env .:

PROD Env。 与NGINX:

任何想法NGINXconfiguration中要改变什么,以便NGINX传递Django设置的头文件?
nginx conf。 看起来像这样:
events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; sendfile on; keepalive_timeout 65; include /path/to/sub_conf/*.conf; }
nginx服务器conf。 包括通过子conf:
server { listen 80; server_name localhost1; location / { proxy_pass http://127.0.0.1:8000; } }
显然你可以设置proxy_ignore_headers来让Nginx不改变你的头。
proxy_ignore_headers Cache-Control Expires Pragma;
这可能是修复它的最简单的方法。 你看到的可能是Nginx的这个特性造成的:
Change: now nginx does not cache by default backend responses, if they have a "Set-Cookie" header line.
大概他们没有这个理由,但我不能解释为什么这个function被实现。
然而,如果你试图强制所有caching被禁用,因为“IEcachingajax请求大量”,你可能有一个更好的解决scheme,只需附加一个唯一的编号到每个Ajax请求,这是一个更强大的方式强制客户端caching响应。
问题不在于nginx没有传递在django源代码中设置的头文件,而是nginx将所有的客户头文件都放在了下划线中。
由于Django在调用request.is_ajax()时正在寻找HTTP_X_REQUESTED_WITH头,所以请求从未被识别为ajax请求,因此没有设置no-cache头。
def is_ajax(self): return self.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
问题解决了在nginxconfiguration中将underscores_in_headers设置为on 。 这篇文章指出了我正确的方向。