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


我们正在使用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好的 更改文件时使用修改后的文件进行响应。
但是,它似乎与Javascript或CSS文件的行为不同。一旦文件被更改,我们就会得到一个 200好的 按预期回应,但旧文本。
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 guest虚拟机Ubuntu上,并且从Mac OSX主机上的共享文件夹中读取数据。
如果文件是从主机上的IDE(NetBeans)编辑的,则似乎不会出现更改,而如果我直接在guest虚拟机上编辑它(使用VIM),则会刷新该文件。
奇怪的是它与HTML文件的行为不相似。
相当令人费解。

编辑2(答案)
实际上,问题的根源在于VirtualBox方面。或者更确切地说,VirtualBox与服务器的“sendfile”选项之间存在冲突。
这个链接 VirtualBox讨厌Sendfile 给了我解决方案:切换 发送文件 标志在服务器配置中

sendfile  off;

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


87
2018-05-13 14:18




你在流浪者vm中运行nginx并使用共享fs吗?在#nginx中有几个使用该组合的症状的报告。 - kolbyjack
我可以真的拥抱你!已经花了48个小时诅咒并且对这个确切的问题感到非常生气..,重新编译nginx几次,牺牲了一些小蓬松的生物到各种各样的神灵,向后学习缓存指令......所有这些都是为了找出它是一个奇怪的修复线感谢VirtualBox很奇怪! - James Butler
如果您将答案作为答案发布并接受它,那么每个人都可以看到这个问题已经解决,那将会更加清晰。 - Zombaya
这对我帮助很大。谢谢。 - Matt M.
今天早上我被这个虫子击中了。如果没有这个,就不会意识到它归于共享文件夹。谢谢! - Jaffa The Cake


答案:


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

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

sendfile  off;

sendfile 是Nginx成名的核心(超快的低级静态文件服务效率),它可能是本地开发的祸根,例如:经常更改并需要重新加载的Javascripts。尽管如此,Nginx sendfile很聪明,可能不是大多数人的问题;检查浏览器的“禁用缓存”选项!


58
2017-11-19 09:52



尽管答案应该解释为+1 为什么 这是必要的,而不是有效地让读者找到/重新阅读寻找参考的问题。让答案自己 - >更好。 - AD7six
这似乎是我的答案。 Sendfile,VirtualBox和OSX主机的特定组合似乎会出现此问题。 abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile  forums.virtualbox.org/viewtopic.php?f=1&t=24905 - Steve Bennett
sendfile 对于当地的发展环境来说也很好;它只是破坏它的VirtualBox。这是(很多)的一个原因我建议避免使用VirtualBox ... - Michael Hampton♦
感谢Vagrant / VirtualBox / Ubuntu / Wordpress的保存,奇怪的问题,我猜我的PROD环境是安全的,默认情况下使用sendfile。 - sonjz
用nginx和docker解决了我的问题 - PascalTurbo


将expires标记设置为

expires off;

并且它根本不应设置任何expires头,它也可能是您的浏览器缓存文件错误


15
2018-05-13 14:20



不幸的是,我也尝试过这个 expires -1 而且行为仍然是一样的。 - Olivier Chappe
关于浏览器,我已经想到了这种可能性:我第一次尝试使用Chrome,并且在修改文件后第一次在Firefox中打开它:我仍然得到了该文件的第一个版本。 - Olivier Chappe
缓存控制头也应该是CACHE-CONTROL:NO-CACHE - anthonysomerset
或完全删除缓存控件标题 - 抱歉无法编辑以前的评论 - anthonysomerset
在Windows上,“expires off”仍然不会禁用html文件的缓存。我在IDE中更新文件时非常令人沮丧,但是!$#%ing nginx服务于旧版本。 - Dan Dascalescu


如果上面没有提到任何帮助,并且仍然Nginx返回您的文件的旧内容,它可能与问题有关 open_file_cache

参见参考:


2
2017-10-14 20:38





这是VirtualBox中的旧错误(请参阅: #819#9069#12597#14920)其中vboxvfs似乎有一些问题,mmapped访问同步的文件。

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

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

对于 Nginx (在某一方面的变化 nginx.conf),例如

sendfile off;

类似于Apache(in httpd.conf 或者在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代表释放pagecache,2代表dentries和inode,3代表pagecache,dentries和inode。


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


2
2017-12-13 14:03





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

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

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


1
2017-12-28 01:47