Las redirecciones de servidor son importantes para redirigir el tráfico entre http y https o para redirigir el dominio a su prefijo con www. Los administradores de los sitios web las usan para actualizar las URL de sus artículos sin perder el linkbuilding y el posicionamiento.
Nginx es muy flexible y tiene varias directivas parar crear redirecciones. return
es eficiente y fácil de usar. Con rewrite
es posible crear redirecciones usando expresiones regulares y para mantener un largo listado de redirecciones usamos map
.
En este artículo te explico como funcionan y las diferencias entre return
, rewrite
y map
.
1. Redirección simple
La directiva return es la forma más sencilla de hacer una redirección 301 o 302 con Nginx.
Este es su modo de empleo:
return (301 | 302 | 303 | 307) URL;
Tiene dos parámetros:
- Código de respuesta
301
,302
,303
ó307
- Es la cabecera HTTP que se envía como respuesta desde el servidor.
La redirección 301 indica al navegador que es una redirección permanente. De este modo, el navegador recordará la configuración para las sucesivas visitas y realizará la redirección internamente reduciendo el número de peticiones al servidor.
Utilizamos el código 302 para crear redirecciones temporales. URL
- Indica la nueva dirección web.
Hay que tener en cuenta que solo es posible usar la directiva return
dentro de un bloque server
o un bloque location
. Como en este ejemplo, donde todo el tráfico http del dominio example.com es redirigido hacia example.org con protocolo seguro (https).
# Redirigir example.com y www.example.com a example.org con un 301
server {
listen 80;
listen [::]:80;
hostname example.com www.example.com;
# ...
return 301 https://example.org$request_uri;
}
La directiva return
es apropiada para redirigir el tráfico de http a https o al revés y para redirigir entre el dominio con www y sin www. A continuación encontrarás ejemplos de configuración para cada caso:
Ejemplo 1. Forzar el uso de SSL/TLS
Esta configuración sirve para redirigir todo el tráfico http del servidor hacia https:
# Redirigir todo el tráfico http a https
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
Y esta es la configuración para redirigir de http a https pero solo para uno de los dominios que tiene configurado el servidor:
# Redirigir http a https para example.org y www.example.org
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.org www.example.org;
return 301 https://$server_name$request_uri;
}
Ejemplo 2. Redirección canónica
Cuando un servidor tiene un único sitio con varios alias es importante hacer una redirección desde los alias al dominio principal para evitar sitios con contenido duplicado.
Si el hostname del servidor coincide con el nombre del dominio principal es posible crear la redirección del siguiente modo:
# Redirigir alias al hostname canónico
server_name example.org www.example.org example.com www.example.com _;
if ( $host != $server_name ) {
return 301 $scheme://$server_name$request_uri;
}
Ejemplo 3. Redirección entre el dominio con y sin www
Esta configuración sirve para redirigir todas las peticiones de cualquier dominio hacia sí mismo pero con www.
# Redirigir a www
if ( $host !~ ^www\. ) {
return 301 $scheme://www.$host$request_uri;
}
Y la configuración contraria que redirige cualquier petición que llegue a un dominio con www al mismo dominio sin el prefijo:
# ...
# Redirigir a sin www
if ( $host ~ ^www\.(?<domain>.+)$ ) {
return 301 $scheme://$domain$request_uri;
}
2. Redirección con patrones
Con Nginx es posible hacer redirecciones basadas en variables y expresiones regulares utilizando la directiva rewrite
.
Con una expresión regular capturamos una parte de la URL original para luego usarla en la URL de destino. De este modo, es posible hacer migraciones SEO sin perder el posicionamiento ni los enlaces de otros sitios (linkbuilding).
Al igual que la directiva return
, rewrite estará siempre dentro de un bloque server
o uno location
. Este es su modo de empleo:
rewrite regex URL [flag];
regex
- Es el expresión regular.URL
- Indica la nueva dirección web y podemos usar variables de captura.flag
- Es opcional y puede tomar uno de estos valores:permanent
,redirect
,last
obreak
.permanent
yredirect
añaden un código de respuesta 301 y 302 respectivamente.
Las etiquetaslast
ybreak
finalizan la ejecución de las instrucciones del bloque donde se encuentran. La diferencia entre ambas es quebreak
retorna inmediatamente una respuesta de servidor, mientras quelast
buscará coincidencias con el resto de bloqueslocation
para aplicar nuevas instrucciones.
Aquí puedes ver un ejemplo:
rewrite ^/foo/(bar)/(.*)$ https://$server_name/$1/$2 permanent;
Diferencias entre return y rewrite
A diferencia de la directiva return
, rewrite
no finaliza el procesamiento de la petición. De este modo, Nginx continúa procesando el resto de instrucciones del bloque a menos que exista una directiva return
.
Otra diferencia es que rewrite solo devuelve un código de respuesta 301 (etiqueta permanent
) o 302 (etiqueta redirect
). Para devolver otros códigos hay que añadir una directiva return en el mismo bloque.
A la hora de elegir entre ambas, siempre que sea posible, usa return
ya que la directiva rewrite
consume más tiempo en interpretar la expresión regular.
3. Mapa de redirecciones
Cuando hay que hacer muchas redirecciones es poco práctico escribir cada instrucción return
o rewrite
dentro del bloque server
o location
. Como en este ejemplo:
location / {
rewrite url-anterior1 url-nueva1 permanent;
rewrite url-anterior2 url-nueva2 permanent;
rewrite url-anterior4 url-nueva3 permanent;
# ...
rewrite url-anterior1000 url-nueva1000 permanent;
}
Con Nginx es posible organizar las redirecciones en un archivo de configuración independiente usando la directiva map
. Para entender como funciona esta técnica es necesario conocer como funciona map
:
map cadena $variable {
clave-1 valor-1;
clave-2 valor-2;
# ...
}
map
crea una nueva variable llamada $variable
cuyo valor es el resultado de buscar
el parámetro cadena
en un conjunto de datos clave-valor dados como último parámetro.
Así, con map
creamos un conjunto de datos formado por URLs a las que corresponde una redirección. Vamos a ver paso a paso un ejemplo de configuración completo:
Paso 1. Crear el mapa de redirecciones
Dentro del directorio de configuración de Nginx, crearemos un nuevo fichero llamado mapa-de-redirecciones.conf:
map $request_uri $nueva_uri {
/acerca-de.html /acerca-de;
/clientes.html /clientes;
# Cualquier url que termine en producto.html
~producto\.html?$ /productos;
# Igual que el anterior sin distinguir mayúsculas y minúsculas
~*producto\.html?$ /productos;
# expresión regular con captura de elementos
# convierte producto-1234.html en /productos/item-1234/descripcion
~producto-(?<sku>\d+)\.html /productos/item-$sku/descripcion;
}
Notas:
request_uri
es una variable de Nginx que contiene la URI original y completa de la petición.
Es posible crear mapas en base a otras variables de Nginx como:$scheme
,$host
,$server_name
o$request_filename
.- A la hora de crear los patrones hay que tener en cuenta que Nginx usa expresiones regulares de Perl (PCRE) y que soporta captura de elementos con la sintaxis:
?<name>
Paso 2. Redirigir si hay coincidencia en el mapa
Por último, hay que incluir el fichero de redirecciones para luego comprobar si existe $nueva_uri
como nueva variable:
include mapa-de-redirecciones.conf;
server {
# ...
if ( $nueva_uri ) {
return 301 $nueva_uri;
}
}
El funcionamiento es así: cuando llega una solicitud al servidor, Nginx buscará el valor de $request_uri
en el mapa de redirecciones. Si encuentra una coincidencia creará la variable $nueva_uri
con el valor asociado a la clave. En caso, contrario la variable no existirá durante el procesamiento de la petición.
Dentro del bloque server
, existe un if
que comprueba la existencia de la variable $nueva_uri
y, en caso de existir, crea una respuesta con la redirección y finaliza el procesamiento de la petición.
Como puedes ver existen varias maneras de crear redirecciones con Nginx. La directiva return
es apropiada para redirigir el tráfico entre http y https o entre el dominio con y sin www. Mientras que con rewrite
es posible hacer redirecciones basadas en patrones complejos.
Por último te he explicado una técnica para organizar un gran número de redirecciones con map
.
César Maeso