Nginx

nginx:在重寫的位置塊中指定自定義標頭

  • March 4, 2016

我正在嘗試僅為locationnginx 中的特定塊設置一些標頭。

我遇到的問題是這些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.txt: Cache-Control: public, 沒有Expires標題
  • f2.txt: Cache-Control: public, 沒有Expires標題

這對f1.txt但不是有效的f2.txt。我希望它是這樣的:

  • f1.txt: Cache-Control: public, 沒有Expires標題
  • f2.txt: Cache-Control: max-age=some huge value,Expires: 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;
}

問題是在我的真實配置文件中,它rewrite看起來並不友好。重寫的 URL不容易匹配,也不會匹配一些不應該有的文件expires max,所以我不能真正使用這個解決方法。

有沒有辦法讓這些標題在 a 之後粘住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;
}

雖然我可以添加一個location塊來/img處理使用第一個規則重寫的文件rewrite,但我不能為第二個規則添加一個 ( /posts),因為其中的某些文件/posts不是可記憶體的資源,因此不應該具有expires max.

編輯 2:完整配置(或至少包含所有相關部分):

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:/somepath搭配Cache-Control: public
  • GET /somepath/img/f1.png:/somepath/img/f1.png搭配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搭配Cache-Control: public
  • GET /somepath/posts/d1/f2.png:/somepath/posts/d1/f2.png搭配Cache-Control: public
  • GET /somepath/posts-img/d1/f2-res-whatever.png/somepath/posts/d1/f2.png與發送的標頭一起使用expires max

這應該可以工作(不過,我用更簡單的配置驗證了這一點)。順便說一句,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;
   }

對於不區分大小寫的位置匹配

location ~* /static/

不區分大小寫刪除“ ***** ”

location ~* /static/

源 Nginx 位置指令文件

引用自:https://serverfault.com/questions/459888