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


89

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

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未修改只要该文件没有改变,和200 OK与响应更改文件后的修改文件。
但是,它与Javascript或CSS文件的行为似乎有所不同。更改文件后,我们将收到200 OK预期的响应,但带有旧文本。
Nginx中是否有内部缓存机制可以解释这种行为?还是我们应该添加的一些配置?

附带说明一下,这是修改文件后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标头尝试其他设置之后,我进行了一些进一步的研究。实际上,服务器安装在VirtualBox来宾Ubuntu上,并且从Mac OSX主机上的共享文件夹中读取数据。
如果从主机上的IDE(NetBeans)编辑了文件,则似乎未显示更改,而如果我直接在来宾(使用VIM)上对其进行编辑,则会刷新文件。
奇怪的是,它与HTML文件的行为不同。
相当令人困惑。

编辑2(ANSWER)
确实,问题的根源更多在VirtualBox方面。或更确切地说,VirtualBox与服务器的“ sendfile”选项之间存在冲突。
此链接VirtualBox讨厌Sendfile给我解决方案:将服务器配置中的sendfile标志切换为off

sendfile  off;

希望这也可以帮助其他人使用VirtualBox进行开发。:) VirtualBox论坛
上还有一些其他信息。


3
您是否在无所事事的虚拟机中运行nginx并使用共享的fs?在#nginx中使用该组合有几处有关您的症状的报告。
kolbyjack

3
我真的可以拥抱你!已经花费了48个小时进行诅咒,并对这个确切的问题完全发狂..,重新编译了nginx几次,将一些蓬松的小动物献给了各种神灵,向后学习了高速缓存指令...所有这些都发现修复这一行很奇怪由于VirtualBox很奇怪!
詹姆斯·巴特勒

13
如果您将答案发布为答案并接受它,这样每个人都可以看到此问题已解决,那就更加清楚了。
Zombaya 2012年

今天早上我被这个虫子击中了。没有这个,就不会意识到它属于共享文件夹。谢谢!
JaffaTheCake 2012年

谢谢!据我了解,目前没有其他方法可以修复此错误?如果需要启用sendfile怎么办?:-)
Dmitry Belaventsev

Answers:


57

由于答案以某种方式隐藏在问题中-这是VirtualBox环境中nginx作为独立答案的解决方案。

在您的nginx配置(通常是/etc/nginx/nginx.conf)或vhost配置文件中,将sendfile参数更改为off

sendfile  off;

尽管这sendfile是Nginx的名声(快速的低级静态文件服务效率)的核心,但它可能会阻碍本地开发,例如,经常更改且需要重新加载的Javascript。尽管如此,Nginx sendfile很聪明,可能不是大多数人的问题。还要检查浏览器的“禁用缓存”选项!


5
+1尽管答案应该说明为什么这样做是必要的,而不是有效地让读者去查找/重新阅读问题以寻找参考。使答案独立存在->更好。
AD7six 2014年

2
这似乎是我的答案。该问题似乎与Sendfile,VirtualBox和OSX主机的特定组合一起发生。abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile forums.virtualbox.org/viewtopic.php?f=1&t=24905
史蒂夫·贝内特

sendfile即使对于本地开发环境也很好;它只是其中损坏的VirtualBox。这是(很多原因中的)一个原因,我建议避免使用VirtualBox ...
Michael Hampton

感谢Vagrant / VirtualBox / Ubuntu / Wordpress的保存,奇怪问题,我猜我的PROD环境默认为sendfile时是安全的。
sonjz

用nginx和
docker

15

将到期标记设置为

expires off;

而且它根本不应该设置任何过期标题,也可能是浏览器错误地缓存文件


不幸的是,我也尝试过这种方法,expires -1并且行为仍然相同。
奥利维尔·查普

关于浏览器,我已经想到了这种可能性:我首先尝试使用Chrome,并在修改文件后首次在Firefox中打开该文件:我仍然获得该文件的第一个版本。
奥利维尔·查普

缓存控制标头也应该是CACHE-CONTROL:NO-CACHE
anthonysomerset 2011年

或完全删除缓存控制标头-很抱歉,无法编辑以前的评论
anthonysomerset,2011年

1
在Windows上,“过期”仍不会禁用html文件的缓存。当我在IDE中更新文件时,超级沮丧,但是!$#%ing nginx提供了旧版本。
Dan Dascalescu 2014年


2

这是VirtualBox中的旧错误(请参阅:#819#9069#12597#14920),其中vboxvfs似乎对映射文件的映射访问存在一些问题。

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

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

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

sendfile off;

与Apache类似(在httpd.confvhosts文件中或在vhosts文件中),例如

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

更改后,重新加载Apache。


其他可能的解决方案是记住不要编辑主机上的文件,或者尝试重新编辑同一文件,但不要在VM内。


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

echo 1 > /proc/sys/vm/drop_caches

或每秒清除一次缓存(如本篇文章所述),请尝试:

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

注意:数字1表示释放页面缓存,数字2表示牙科和索引节点,数字3表示页面缓存,牙科和索引节点。


可以通过以下mmap-test程序来复制上述问题,请参阅:mmap-problem.c


1

已经很晚了,但是仍然标记为未回答,因此我将采取行动。只是为了咯咯地笑,您是否尝试过:

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

我自己还没有尝试过,但是当我遇到类似问题时,不时学会在服务器容器中使用Nginx尝试这种事情...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.