2013-11-15 26 views
2

我试图告诉nginx永远缓存我的一些资产(js,css),或者至少很长一段时间。通过Nginx无限期地缓存HTTP响应失败

的想法是,一旦资产包被编译并与/assets/ URI前缀(如/assets/foo-{fingerprint}.js)公布它就留在那里,并不需要更改。

的互联网络告诉我,我应该写如下规则:

location ~ ^/assets/.*-([^.]+)\.(js|css)$ { 
    gzip_static on; # there's also a .gz of the asset 
    expires max; 
    add_header Cache-Control public; 
    add_header Last-Modified ""; 
    add_header ETag ""; 
    break; 
} 

我希望这将导致与HTTP代码304“未修改”响应,但我得到的是一致的HTTP 200(OK ) 每次。

我已经尝试了一些其他的方法,比如:

一)修改时间明确设定在过去的时间常数点;

add_header Last-Modified "Thu, 01 Jan 1970 00:00:00 GMT"; 

b)切换到If-None-Match检查;

add_header ETag $1; 
if_modified_since off; 

然而,仅在需要时真正工作的事情是这样的:

add_header Last-Modified "Thu, 01 Jan 2030 00:00:00 GMT"; 
if_modified_since before; 

我迷路了。这与我认为是正确的一切相反。请帮忙。

回答

6

你应该改变你的网络,因为他们给你错误的建议。

只是删除从您的位置所有add_header线(以及剩余brake):

location ~ ^/assets/.*-([^.]+)\.(js|css)$ { 
    gzip_static on; # there's also a .gz of the asset 
    expires max; 
} 

,并宣读了真正的互联网文档:http://nginx.org/r/expireshttp://tools.ietf.org/html/rfc2616

+0

谢谢,但有一个例外的工作原理:每当资产'touch'ed缓存被捣毁。我不希望高速缓存被破坏。是否有可能让Nginx忽略/覆盖服务资产的“mtime”? – krukid

+0

关于我的web设置的一件事是,我部署到多个服务器并在每个部署中同步'mtime',因为我的旧缓存清除方法基于'mtime'。现在我试图转向基于指纹的缓存清除,但是当这两种方法都必须起作用时,会有一个过渡期,所以我必须同步mtime来提供指纹资产而不会破坏缓存。 – krukid

+0

无论如何,现在我正在考虑从'mtime'同步中排除新资产,但我认为FS'mtime'只能通过Last-Modified HTTP头来缓存缓存,并且用Nginx规则覆盖缓存应该可以解决问题。 – krukid

-1

看来我配置的一部分。在我的研究过程中,我意识到浏览器使用启发式分析来使用ConditionalGet标头(E-Tag,Last-Modified)验证请求。它对于后端响应很有意义,所以您可以处理它以节省服务器资源。

但是就静态文件(js,css,images)而言,您可以告诉浏览器在没有任何条件获取验证的情况下立即提供服务。如果发生更改,则更新文件名是有帮助的。

这部分配置使得它发生:

add_header Cache-Control public; 
add_header Last-Modified ""; 
add_header ETag "";