2009-10-27 19 views
37

Ich sehe die Nginx HttpRewriteModule documentation ein Beispiel hat eine www-Präfix Domain zu einer nicht-www-Präfix Domäne neu zu schreiben:Nginx Rewrite nicht-www-Präfix-Domain www-Präfix Domain

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

Wie kann ich Machen Sie das Umgekehrte - schreiben Sie eine nicht-www-Präfix-Domain in eine www-Präfix-Domain um? Ich dachte, ich könnte vielleicht etwas wie das Folgende machen, aber Nginx mag die verschachtelte if-Anweisung nicht.

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

Auch wollte ich dies, ohne explizit für jeden Domain-Namen arbeiten Nginx zu sagen domain1.com neu zu schreiben -> www.domain1.com, domain2.com -> www.domain2.com usw., da ich eine große Anzahl von Domains neu schreiben.

Antwort

13

Nun, ich denke, ich brauche die äußere "if" -Anweisung nicht wirklich, da ich sowieso nur nach Domänen der Form xxx.xxx suche. Das Folgende funktioniert für mich, obwohl es nicht robust ist. Lassen Sie mich wissen, ob es eine bessere Lösung gibt.

Bearbeiten: Bindestrich zum regulären Ausdruck hinzugefügt, da es ein gültiges Zeichen in einem Hostnamen ist.

+0

wie verwende ich das ohne wenn? – pahnin

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

Dies funktioniert nicht für mich, weil ich Subdomains wie static.mydomain.com nicht neu schreiben möchte. Ich hätte das wahrscheinlich in meiner Frage gesagt. Danke für deine Antwort. – saltycrane

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

Es ist nur möglich, gültige Host-Namen zu erhalten, weil die Anforderung es nie anders auf Ihren Server machen wird, so gibt es keine Notwendigkeit, Ihre eigene Validierungslogik zu bauen.

57

As noted in the Nginx documentation, you should avoid using the if directive in Nginx where possible, denn sobald Sie ein if in Ihrer Konfiguration haben Ihr Server jede einzelne Anfrage bewerten muss zu entscheiden, ob sie übereinstimmen, dass if oder nicht.

Eine bessere Lösung wäre mehrere Server-Richtlinien.

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

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

Wenn Sie versuchen, eine SSL (HTTPS) aktiviert Website zu dienen, haben Sie mehr oder weniger drei verschiedene Optionen.

  1. Richten Sie mehrere IP-Adressen ein, wobei jede Server-Richtlinie auf ihrer eigenen IP-Adresse (oder anderen Ports, wenn dies eine Option für Sie ist) abhört. Diese Option benötigt SSL-Zertifikate für beide website.com und www.website.com, so entweder Sie ein Wildcard-Zertifikat, ein UNI-Zertifikat (mehrere Domänen) oder einfach nur zwei verschiedene Zertifikate haben.
  2. In der Anwendung neu schreiben.
  3. Verwenden Sie die gefürchtete if Richtlinie.

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

+0

Ihr einfacher Code hat den Trick gemacht. Vielen Dank! –

+0

Diese Lösung hat den zusätzlichen Vorteil, dass ein HTTP 301 Moved Permanently-Antwortstatuscode gesendet wird. Dies ist eine effiziente, elegante und lesbare Lösung. Vielen Dank! – ndmeiri