使用Nginx提供静态文件时禁用caching(用于开发)

我们正在使用Nginx在开发平台上提供静态文件。 由于这是一个开发平台,我们希望禁用caching,以便将每个更改传播到服务器。 VHost的configuration非常简单:

server { server_name static.server.local; root /var/www/static; ## Default location location / { access_log off; expires 0; add_header Cache-Control private; } } 

当我们访问一个HTML文件( http://static.server.local/test.html )时,我们没有问题:只要文件没有改变,服务器返回代码304 Not Modified ,并且200 OK响应文件更改时的修改文件。
但是,它似乎与Javascript或CSS文件的行为不同。 一旦文件被改变,我们得到一个200 OK的响应,如预期的,但与旧的文字。
Nginx中是否有一个内部caching机制可以解释这种行为? 或者我们应该添加一些configuration?

作为一个附注,这里是Nginx在文件被修改时返回的头文件(看起来是正确的):

 Accept-Ranges:bytes Cache-Control:max-age=0 private Connection:keep-alive Content-Length:309 Content-Type:text/css Date:Fri, 13 May 2011 14:13:13 GMT Expires:Fri, 13 May 2011 14:13:13 GMT Last-Modified:Fri, 13 May 2011 14:13:05 GMT Server:nginx/0.8.54 

编辑
在尝试使用expires指令和Cache-Control头的不同设置expires ,我做了一些进一步的调查。 实际上,服务器安装在VirtualBox的客户端Ubuntu上,数据是从Mac OSX主机上的共享文件夹中读取的。
如果从主机上的IDE(NetBeans)编辑该文件,则似乎不会显示更改,而如果直接在来宾(使用VIM)编辑该文件,则会刷新该文件。
奇怪的是,它不像HTML文件一样。
相当令人费解。

编辑2(答案)
事实上,这个问题的来源更多的是在VirtualBox方面。 或者说VirtualBox和服务器的“sendfile”选项之间的冲突。
这个链接VirtualBox恨发送文件给了我的解决scheme:将服务器configuration中的发送文件标志closures

 sendfile off; 

希望这也可以帮助其他人使用VirtualBox进行开发。 🙂
在VirtualBox论坛上有一些额外的信息。

由于答案在某种程度上隐藏在这个问题中 – 下面是作为独立答案的VirtualBox环境中的nginx解决scheme。

在你的nginxconfiguration(通常是/etc/nginx/nginx.conf)或者vhostconfiguration文件中,将sendfile参数改为off

 sendfile off; 

尽pipesendfile是Nginx声誉(快速的低级静态文件服务效率)的核心,但是对于本地开发来说,这可能是一个麻烦,例如经常变化并需要重新加载的Javascript。 尽pipeNginx的sendfile很聪明,可能不是大多数人的问题; 检查您的浏览器的“禁用caching”选项!

设置您的过期标签

 expires off; 

它不应该设置任何过期头,也可能是您的浏览器caching文件不正确

这是VirtualBox中的旧bug(请参阅: #819 , #9069 , #12597 , #14920 ),其中vboxvfs似乎在对同步文件进行mmapped访问时存在一些问题。

当您在VM之外编辑文件时,可能会发生这种情况,并且您希望在VM中看到相同的更改。

要解决此问题,您需要禁用内核sendfile支持以通过禁用EnableSendfile选项将文件传送到客户端。 这对NFS或SMB挂载文件尤其麻烦。

对于Nginx (改变nginx.conf ),例如

 sendfile off; 

类似的Apache(在httpd.conf或在vhosts文件),例如

 <Directory "/path-to-nfs-files"> EnableSendfile Off </Directory> 

更改后重新加载Apache。


其他可能的解决scheme是记住不要编辑主机上的文件,或者尝试重新编辑同一个文件,但是在虚拟机中。


另一个解决方法包括删除Linux页面caching,例如

 echo 1 > /proc/sys/vm/drop_caches 

或者每秒清除caching(按照这篇文章 ),请尝试:

 watch -n 1 $(sync; echo 1 > /proc/sys/vm/drop_caches) 

注意:编号1代表释放页面caching,代表2个用于deniser和inode,3代表页caching,dentries和inode。


上面的问题可以通过下面的mmap-test程序来复制,参见: mmap-problem.c

这已经很晚了,但仍然没有回答,所以我会采取刺。 只是为了咯咯笑,你有没有试过:

 location ~* \.(css|js)$ { expires 0; break; } 

自己没有尝试过这个,但是当我遇到类似这样的问题的时候,已经学会了用Nginx在服务器容器中尝试这种事情…

如果上面没有提到有帮助,而且Nginx仍旧返回文件的旧内容,那么可能与open_file_cache有关。

看作为参考: