2009-10-27 12 views
37

widzę Nginx HttpRewriteModule documentation ma przykład do przepisywania domenę www-prefiksem do domeny non-www-prefiksem:Nginx przepisać non-www-prefiksem domeny www-prefiksem domenie

if ($host ~* www\.(.*)) { 
    set $host_without_www $1; 
    rewrite ^(.*)$ http://$host_without_www$1 permanent; # $1 contains '/foo', not 'www.mydomain.com/foo' 
} 

Jak mogę zrobić odwrotnie - przepisać domenę bez prefiksów www na domenę z prefiksem www? Pomyślałem, że może mógłbym zrobić coś takiego, ale Nginx nie lubi zagnieżdżonej instrukcji if.

if ($host !~* ^www\.) {      # check if host doesn't start with www. 
    if ($host ~* ([a-z0-9]+\.[a-z0-9]+)) { # check host is of the form xxx.xxx (i.e. no subdomain) 
     set $host_with_www www.$1; 
     rewrite ^(.*)$ http://$host_with_www$1 permanent; 
    } 
} 

Również chciałem to do pracy dla każdej nazwy domeny bez wyraźnie mówi Nginx przepisać domain1.com -> www.domain1.com, domain2.com -> www.domain2.com itp ponieważ mam duża liczba domen do przepisania.

Odpowiedz

13

No cóż, tak naprawdę nie potrzebuję zewnętrznej instrukcji "if", ponieważ sprawdzam tylko domeny formularza xxx.xxx. Poniższe działa dla mnie, choć nie jest solidne. Daj mi znać, jeśli istnieje lepsze rozwiązanie.

if ($host ~* ^([a-z0-9\-]+\.(com|net|org))$) { 
     set $host_with_www www.$1; 
     rewrite ^(.*)$ http://$host_with_www$1 permanent; 
    } 

Edytuj: Dodano myślnik do wyrażenia regularnego, ponieważ jest to poprawny znak w nazwie hosta.

+0

jak tego użyć bez, jeśli? – pahnin

15
if ($host !~* ^www\.) { 
    rewrite ^(.*)$ http://www.$host$1 permanent; 
} 
+1

Nie działa to dla mnie, ponieważ nie chcę przepisywać subdomen takich jak static.mydomain.com. Prawdopodobnie powinienem o tym powiedzieć w moim pytaniu. Dzięki za odpowiedź. – saltycrane

6
if ($host ~* ^[^.]+\.[^.]+$) { 
    rewrite ^(.*)$ http://www.$host$1 permanent; 
} 

Jest to możliwe tylko, aby uzyskać poprawne nazwy hostów, ponieważ żądanie nigdy nie pozwoli na serwer inaczej, więc nie ma potrzeby, aby zbudować swoją własną logikę walidacji.

57

As noted in the Nginx documentation, you should avoid using the if directive in Nginx where possible, bo jak tylko masz if w konfiguracji serwer musi ocenić każdy wniosek o decyzję, czy zgadza się, że if czy nie.

Lepszym rozwiązaniem byłoby zastosowanie wielu dyrektyw serwera.

server { 
     listen 80; 
     server_name website.com; 
     return 301 $scheme://www.website.com$request_uri; 
} 

server { 
     listen 80; 
     server_name www.website.com; 
     ... 
} 

Jeśli próbujesz wyświetlić witrynę obsługującą SSL (HTTPS), masz mniej lub więcej trzy różne opcje.

  1. Skonfiguruj wiele adresów IP, w których każda dyrektywa serwera nasłuchuje na ich własnym IP (lub różnych portach, jeśli jest to opcja dla ciebie). Ta opcja wymaga certyfikatów SSL dla domeny website.com i www.website.com, więc możesz mieć certyfikat karty wieloznacznej, certyfikat UNI (wiele domen) lub tylko dwa różne certyfikaty.
  2. Wykonaj przepisanie w aplikacji.
  3. Skorzystaj z przerażającej dyrektywy if.

There is also an option to use SNI, but I'm not sure this is fully supported as of now.

+0

Twój prosty kod załatwił sprawę. Wielkie dzięki! –

+0

To rozwiązanie ma dodatkową zaletę polegającą na odesłaniu kodu statusu przeniesienia HTTP 301 na stałe. Jest to wydajne, eleganckie i czytelne rozwiązanie. Dzięki! – ndmeiri