2009-10-27 18 views
37

que ver el Nginx HttpRewriteModule documentation tiene un ejemplo de reescribir un dominio www-prefijado a un dominio sin www-prefijo:Nginx reescritura de dominio prefijado la no-www al dominio www-prefijo

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

¿Cómo puedo hacer lo contrario: reescribir un dominio que no tiene prefijo www en un dominio prefijo www Pensé que tal vez podría hacer algo como lo siguiente, pero a Nginx no le gusta la declaración if anidada.

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

También quería que esto funcione para cualquier nombre de dominio sin decirle explícitamente Nginx para reescribir domain1.com -> www.domain1.com, domain2.com -> www.domain2.com, etc. ya que tengo una gran cantidad de dominios para reescribir

Respuesta

13

Bueno, supongo que realmente no necesito la declaración externa "si", ya que solo estoy buscando dominios de la forma xxx.xxx. Lo siguiente funciona para mí, aunque no es robusto. Avíseme si hay una mejor solución.

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

Editar: Añadido guión para la expresión regular, ya que es un carácter válido en un nombre de host.

+0

cómo usar esto sin? – pahnin

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

Esto no funciona para mí porque no quiero volver a escribir subdominios como static.mydomain.com. Probablemente debería haber dicho eso en mi pregunta. Gracias por tu respuesta. – saltycrane

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

Sólo es posible obtener los nombres de host válidos debido a que la solicitud nunca llegará a su servidor de lo contrario, así que no hay necesidad de construir su propia lógica de validación.

57

As noted in the Nginx documentation, you should avoid using the if directive in Nginx where possible, porque tan pronto como usted tiene una if en la configuración de su servidor tiene que evaluar cada petición para decidir si coincide o no if.

Una solución mejor sería varias directivas de servidor.

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

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

Si usted está tratando de servir a un SSL (HTTPS) está activado, tiene más o menos tres opciones diferentes.

  1. Configure múltiples direcciones IP teniendo cada directiva de servidor escuchando en su propia IP (o diferentes puertos si esa es una opción para usted). Esta opción necesita certificados SSL para website.com y www.website.com, por lo que o bien tiene un certificado de comodín, un certificado UNI (múltiples dominios) o simplemente dos certificados diferentes.
  2. Haga la reescritura en la aplicación.
  3. Utilice la temida directiva if.

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

+0

Su código simple hizo el truco. ¡Gracias un montón! –

+0

Esta solución tiene el beneficio adicional de enviar de vuelta un código de estado de respuesta de HTTP 301 movido permanentemente. Esta es una solución eficiente, elegante y legible. ¡Gracias! – ndmeiri

Cuestiones relacionadas