2012-03-06 60 views
12

nginx文檔說明server_name directive支持正則表達式。我一直在撞牆,試圖讓一個微不足道的正則表達式工作。在nginx中使用正則表達式重定向子域

我想http://subdomain.mydomain.com重定向到http://mydomain.com/subdomain

這裏是我的代碼。

server { 
    server_name "~^subdomain\.mydomain\.com$"; 
    rewrite^http://mydomain.com/subdomain; 
} 

此外,可能值得注意。進一步在nginx配置文件中有一條規則:

server { 
    server_name *.mydomain.com 
    ... 
} 

我在做什麼錯?

UPDATE:

有人建議我不要使用這個...正則表達式來提供多一點清晰:在平凡的正則表達式是簡單地進行故障排除的目的。真正的正則表達式看起來更像...

server { 
    server_name "~^.*(cvg|cincinnati)\.fakeairport(app)?\.(org|com)$"; 
    rewrite^http://fakeairport.com/cincinnati; 
} 

server { 
    server_name "~^.*(lex|lexington)\.fakeairport(app)?\.(org|com)$"; 
    rewrite^http://fakeairport.com/lexington; 
} 

所以最好使用正則表達式。

+0

無能nginx的,但爲什麼會出現在正則表達式的開始波浪? – sweaver2112 2012-03-06 09:18:21

+0

前導代字號告訴nginx這是一個正則表達式。 – danott 2012-03-06 19:03:13

回答

26

要回答一個老問題,以幫助他人

使用nginx的1.1.19,你可以做到以下幾點:

server { 
    server_name  ~^(?<subdomain>\w+)\.domainA\.com$; 

    location/{ 
      rewrite^https://$subdomain.domainB.com$request_uri permanent; 
    } 
} 

domainA.com前的子域名被匹配,並存儲在變量$子域,然後可以用於重寫。 這隻用一個服務器指令就可以將xxx.domainA.com這樣的URL重寫爲xxx.domainB.com。

+0

謝謝你,它幫助了我。 – 2014-05-27 04:02:44

0

我知道每個人都在說如果在nginx配置文件中是邪惡的,但有時你無法繞過任何其他方式。

server { 
     server_name .mydomain.com; 

     if ($host ~ subdomain.mydomain.com) { 
       rewrite ^(.*) http://mydomain.com/subdomain$1; 
     } 
} 
+2

如果不需要,你永遠不要使用它。這只是要求麻煩。 – MTeck 2012-03-06 22:02:15

+1

正確,但正如你所暗示的那樣,有些情況需要時,如果配置正確(僅限重寫模塊命令),使用它是完全安全的。 「如果」的問題不是它不應該被使用,而是它被理解使用。 – Dayo 2012-03-07 03:53:56

+5

我真的厭倦了大多數人說「永遠不要使用」。爲什麼在世界上它甚至被實施,如果它被禁止使用?! – petermolnar 2012-03-07 10:12:51

3

如果你讀了server_name matching rules,你會看到正則表達式的名稱之前的前綴和後綴server_names配置進行檢查,但確切的主機名之後。由於* .mydomain.com匹配,正則表達式未經測試。它在config中早些列出的事實沒有區別。既然你只是想用你的正則表達式匹配一個主機名,一個簡單的:

server { 
    server_name subdomain.mydomain.com; 
    rewrite^http://mydomain.com/subdomain$request_uri?; 
} 

server { 
    server_name *.mydomain.com; 

    # stuff 
} 

將爲你工作。

+0

微不足道的正則表達式僅僅是爲了排除故障的目的。關於爲什麼我需要使用正則表達式的更多細節已添加到原始問題中。 – danott 2012-03-06 16:47:35

+0

啊,我應該意識到這一點。你用什麼後綴域?只要你有它,沒有正則表達式服務器將匹配該後綴。 – kolbyjack 2012-03-06 17:16:07

+0

我們的應用程序的體系結構使用了大量的子域名,因此它被用作全面重定向任何沒有特定重定向的附加子域名。 – danott 2012-03-06 19:05:20

9

得到愛與NGINX的正則表達式!

由於我經常使用多個域名,並且我喜歡保持我的配置儘可能乾淨和堅實,所以我幾乎總是在nginx中使用正則表達式。

在這種情況下,我用下面的正則表達式來解決它:

server { 
    listen 80; 
    server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$; 
    return 301 $scheme://${domain}.${tld}; 
} 

這樣做有什麼如下:每subdomain.domain-name.tld指向該服務器(IP地址)被自動重定向到domain-name.tld

因此,例如www.myexampledomain.com被重定向到myexampledomain.com

要回答這個問題,你也可以做的是以下幾點:

server { 
    listen 80; 
    server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$; 
    return 301 $scheme://${domain}.${tld}/${subdomain}; 
} 

現在mysubdomain.myexampledomain.com轉化爲myexampledomain.com/mysubdomain

以上的正則表達式是偉大的,因爲你喜歡,你可以在它扔任何東西,將其轉換爲您服務。

+1

RegEx在您的示例中的'server_name'中捕獲非常有用!一個夢幻般的獎金是我能夠動態地定義由斬去​​子域,像這樣一個共享'root'路徑:'根\t /home/www-data/$domain.$tld/;'你的答案使用更現代化的技術和應該更新爲接受的答案。 – FactoryAidan 2016-04-28 01:16:59

0

正如評論。如果您想重定向所有子域級別第一分區的水平,UTIL當您使用例如一個通配符SSL證書,你可以使用:

server { 
    listen 80; 
    server_name ~^(.*)\.(?<subdomain>\w+).mydomain\.com$; 
    return   301 https://$subdomain.mydomain.com$request_uri; 
} 

server { 
    listen 80; 
    server_name ~^(?<subdomain>\w+).mydomain\.com$; 
    return   301 https://$subdomain.mydomain.com$request_uri; 
} 

首先是重定向一個HTTP多級子域名的第一分區級在https中。接下來是將http中的第一級子域重定向到https中的相同子域。