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

Modified on: Sat, 21 Sep 2019 18:20:02 +0800

我正在尝试为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

这是我尝试过的配置:

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 header
  • f2.txtCache-Control: public,no Expires header

这对f1.txt有效,但对f2.txt无效。我希望它是这样的:

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

问题,我认为,源于rewrite /static(.*) /whatever$1;行,这使得nginx取消了它到目前为止添加的标题,然后再添加它们(因此重新添加Cache-Control)。因此,一个简单的解决方法是:

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

问题在于,在我的真实配置文件中,rewrite并不像那样友好。重写的URL 不易匹配的方式不会与某些不应该expires max的文件相匹配,因此我无法真正使用此解决方法。

有没有办法让这些标题在rewrite后保持不变?

编辑:以下是我的真实网址:

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

虽然我可以为location添加/img块,它会处理使用第一个rewrite规则重写的文件,但我无法添加一个用于第二个(/posts),因为/posts中的某些文件不是可缓存的资源,因此不应该expires max。< / p>

编辑2:完整配置(或至少包含所有相关部分):

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

目录结构:

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

根据HTTP请求的预期行为:

  • GET /somepath:使用/somepath
  • 提供Cache-Control: public
  • GET /somepath/img/f1.png:使用/somepath/img/f1.png /somepath/img/f1.png / LI>
  • Cache-Control: public:提供GET /somepath/img/f1-res-whatever.png,其中/somepath/img/f1.png
  • expires max:使用GET /somepath/posts/post1.html /somepath/posts/post1.html / LI>
  • /somepath/posts/post1.html:使用Cache-Control: public /代码>
  • GET /somepath/posts/d1/f2.png:提供/somepath/posts/d1/f2.png并发送标头通过Cache-Control: public

最佳答案

这应该可行(虽然我用稍微简单的配置验证了这一点)。顺便提一下,Igor Sysoev建议尽可能少地使用正则表达式位置。

    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;
    }

相关问答

添加新评论