我的目标是使用特定策略缓存具有查询字符串的资产,使用其他策略缓存不具有查询字符串的资产。不幸的是,nginx 会忽略位置块中的查询字符串,因此我只能使用if
/error_page
策略这里:
location /static/ {
alias /home/client/public/;
error_page 418 = @long_lived_caching_strategy;
if ($query_string = "example=querystring") {
return 418;
}
}
location @long_lived_caching_strategy {
etag off;
add_header Cache-Control "public";
expires 1y;
}
}
但是,我的错误日志显示,在上述配置中,该alias
指令被忽略。但是,当我尝试将该alias
指令移入时@long_lived_caching_strategy
,nginx 告诉我alias
那里不允许这样做!
我有什么解决方法?
或者,是否有另一种方法可以根据 URL 是否具有查询字符串来以不同的方式设置etag
和指令?add_header
答案1
我找到了一个更简单的解决方案,感谢这线程。我的目标实际上是根据是否存在查询字符串有条件地添加与缓存相关的标头,而使用if
设置字符串被证明是实现此目的的最简单方法。这是我的最终配置:
location /static {
alias /usr/local/etc/nginx/relative-paths/picasso/client/public;
# If an asset has a query string, it's probably using that query string for cache busting purposes.
set $long_lived_caching_strategy 0;
if ($query_string) { set $long_lived_caching_strategy 1; }
if ($long_lived_caching_strategy = 0) {
# Cache strategy: caches can store this but must revalidate the content with the server using ETags before serving a 304 Not Modified.
set $cache_control "no-cache";
}
if ($long_lived_caching_strategy = 1) {
# Cache strategy: proxy caches can store this content, and it's valid for a long time.
set $cache_control "public, max-age=86400, s-maxage=86400"; # 1 day in seconds
}
add_header Cache-Control $cache_control;
# Some types of assets, even when requested with query params, are probably not going to change and should be cacheable by anyone for a long time.
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|ttf)$ {
add_header Cache-Control "public max-age=86400, s-maxage=86400";
etag off;
access_log off;
}
}
答案2
您可以手动执行此操作,如果您有headers_more编译到 Nginx 中的模块,这是使 add_header 可用的另一种方法。有些发行版会包含这个,你可能需要从源代码构建 Nginx- 这出乎意料的快捷和简单。
add_header Cache-Control "public, max-age=691200, s-maxage=691200";
您不需要使用 expires 标头 -原因就在这里。