nginx:在重写的位置块中指定自定义标题

我正在尝试为nginx中的特定location块设置一些标头。

我遇到的问题是这些location块包含rewrite语句,显然这似乎删除自定义标头。

在这个例子中,我有两个规则:

  • 里面的/static文件应该已经expires max; (其中设置头Cache-Control: max-age=some huge valueExpires: some future date really far off ),并将其名称被重写为不包含/static
  • 其他地方的文件应该有Cache-Control: public (没有max-age

这是我尝试的configuration

 server { listen [::]:80; root /somepath; location /static { expires max; rewrite /static(.*) /whatever$1; } add_header Cache-Control public; } 

并具有以下目录结构:

 /somepath /somepath/f1.txt /somepath/static/f2.txt 

然后我们得到以下内容:

  • f1.txtCache-Control: public ,no Expires标题
  • f2.txtCache-Control: public ,no Expires标题

这对于f1.txt而不是f2.txt是有效的。 我希望它是这样的:

  • f1.txtCache-Control: public ,no Expires标题
  • f2.txtCache-Control: max-age=some huge valueExpires: some future date really far off

我想这个问题源于rewrite /static(.*) /whatever$1; 行,这使得nginx取消已经添加的标题,然后再添加它们(从而重新添加Cache-Control )。 因此,一个微不足道的解决方法是:

 server { listen [::]:80; root /somepath; location /static { rewrite /static(.*) /whatever$1; } location /whatever { expires max; } add_header Cache-Control public; } 

问题是,在我真正的configuration文件中, rewrite不像那样友好。 重写的URL 不容易匹配的方式,不会匹配一些不应该expires max ,所以我不能真正使用此解决方法。

有没有办法让这些头rewrite

编辑 :这是我的真实url的样子:

 location ~ /(?:posts-)?img/.*-res- { access_log off; expires max; rewrite "/img/(.*)-res-.{8}(.*)" /img/$1$2; rewrite "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2; } 

虽然我可以为/img添加一个location块来处理使用第一个rewrite规则重写的文件,但我不能为第二个( /posts )添加一个,因为/posts中的某些文件不是可caching的资源,因此不应该已经expires max

编辑2 :完整的configuration(或至less包含所有相关的部分):

 server { listen [::]:80; root /somepath; server_name domain.tld; location ~ /(?:posts-)?img/.*-res- { access_log off; expires max; rewrite "/img/(.*)-res-.{8}(.*)" /img/$1$2; rewrite "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2; } add_header Cache-Control public; } 

目录结构:

 /somepath /somepath/img/f1.png /somepath/posts/post1.html /somepath/posts/d1/f2.png /somepath/posts/d2/f2.png 

预期的行为根据HTTP请求:

  • GET /somepath :使用Cache-Control: public服务/somepath Cache-Control: public
  • GET /somepath/img/f1.png :用Cache-Control: public提供/somepath/img/f1.png
  • GET /somepath/img/f1-res-whatever.png :提供/somepath/img/f1.png头文件,以expires max
  • GET /somepath/posts/post1.html :用Cache-Control: public提供/somepath/posts/post1.html
  • GET /somepath/posts/d1/f2.png :用Cache-Control: public提供/somepath/posts/d1/f2.png
  • GET /somepath/posts-img/d1/f2-res-whatever.png :供应/somepath/posts/d1/f2.png ,头文件的发送时间为expires max

这应该工作(虽然我用一些简单的configuration来validation)。 顺便说一句,Igor Sysoevbuild议尽可能less地使用正则expression式位置。

  location /img { if ($arg_max) { expires max; } ... } location /posts-img { if ($arg_max) { expires max; } ... } location ~ /(?:posts-)?img/.*-res- { access_log off; expires max; rewrite "/img/(.*)-res-.{8}(.*)" /img/$1$2?max=1; rewrite "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2?max=1; } 

用于不区分大小写的位置匹配 。

 location ~* /static/ 

不区分大小写删除“*****”

 location ~* /static/ 

源代码Nginx位置指令文档