¿Qué son las Rewrite Rules?

Abril 14, 2008 · Imprime esta entrada

Son un conjunto de reglas que se valen de expresiones regulares para poder reescribir solicitudes de direcciones URL “on the fly” y de forma transparente. Son parte del módulo de Apache mod_rewrite y soportan un número ilimitado de condiciones utilizando variables e inclusio los “headers” HTTP para cambios avanzados de las direcciones URL.

En palabras más claras nos permiten reescribir la dirección URL utilizando patrones fáciles de entender para los humanos y haciendolos fáciles de indexar y convertirlos a peticiones que nuestra programación pueda entender. Este módulo es comunmente utilizado para poder usar las denominadas “Clean URL’s” (URL limpias) para hacerlas más lógicas, un ejemplo sería cuando el usuario ve esta URL http://www.dominio.com/buscar/termino y el mod_rewrite se encarga de convertir esa URL en http://www.dominio.com/cgi-bin/buscar.cgi?term=termino.

De esta forma para el usuario es fácil recordar esa URL ya que mantiene una sintaxis más clara de entender. Esta no pretende ser una guía muy extensa del mod_rewrite, si quieres ampliar información puedes verla en la Wikipedia y el sitio de Apache, así como las directivas de configuración.

Algunos usos prácticos de las rewrite rules

  • Permitir que las direcciones URL sean más amigables al usuario y los buscadores.
  • Prevenir el “hot linking” o que usen tus imagenes en otros sitios.
  • Esconder las direcciones web reales de tu servidor a los usuarios.
  • Redirigir de forma transparente las peticiones web.

Es una herramienta muy potente, y nos da muchísimas posibilidades de juego a costa de un pequeño incremento en la carga de procesamiento en el servidor, por lo que no es aconsejable el uso excesivo de estas.

Para habilitarlas es aconsejable hacerlo desde la raíz del servidor web, creando un archivo .htaccess con las siguientes cabeceras

Options +FollowSymLinks
RewriteEngine On
RewriteBase /

Abajo de estas líneas ya pueden empezar a detallarse las reglas que necesitemos configurar.

Desde hace algún tiempo he estado utilizando estas herramientas y me han ayudado a mejorar mi sitio web, son muy fáciles de usar si tienes un mínimo conocimiento de expresiones regulares y de las cabeceras del Apache. Así que me gustaría explicar algunos problemas que me encontre y como los hemos resuelto usando las rewrite rules:

Rewrite rules para el uso de “Clean URL’s”

RewriteRule ^user/(.*)$ /mt/mt-cp.cgi?username=$1 [L]

Esta regla lo que hace es buscar la palabra user seguida de una “/” desde el inicio de linea, es decir, el primer caracter despues del dominio, por ejemplo

http://www.dominio.com/user/edeleon

Si la encuentra reenvía la petición al servidor Apache de la siguiente forma

http://www.dominio.com/mt/mt-cp.cgi?username=edeleon

Y el servidor devuelve al usuario la página sin cambiar la URL en el navegador del usuario. Al usar el flag [L] le decimos al mod_rewrite que esa es la última regla evitando así que las siguientes reglas puedan cambiar el resultado de la petición.

Rewrite rules para el uso de “Clean URL’s” utilizando los “headers HTTP”

RewriteCond %{HTTP_REFERER} www [OR]
RewriteCond %{HTTP_REFERER} docs
RewriteCond %{REQUEST_URI} /user/(.*[^/])
RewriteRule ^user/(.*)$ /mt/mt-cp.cgi?username=$1 [L]

En esta ocasión utilizamos el RewriteCond para condicionar la regla de tal forma que preguntamos si la petición viene de un sitio que contenga www O docs en el dominio Y si la URL contiene /user/ seguida de cualquier caracter que utilice el patrón de RewriteRule para reescribir la petición. Ojo a la forma de utilizar [OR] para que el operador acepte una condicion u otra, y si no lo usamos usa el operador “and” por defecto.

Rewrite Rule para redirigir la petición a otra URL

RewriteRule ^categoria/(.*)$ /category/$1 [R]

Esta regla es útil cuando necesitamos redirigir al usuario a una nueva URL, al usar el “flag” [R] estamos diciendo al mod_rewrite que fuerze la redirección, cambiando la URL en la barra del navegador del usuario y pasando todo el texto despues de “/” como parámetro a la nueva URL.

otra forma de hacer un redirect de forma fácil sería

Redirect permanent /rss/comentarios.xml http://feeds.feedburner.com/my_feef_url

Este ejemplo es práctico si usamos por ejemplo a feedburner como proveedor de nuestros RSS, al usar la directiva Redirect hacemos una redirección del tipo permanente a la nueva URL. De manera que podemos seguir usando nuestras propias direcciones para que los usuarios se subscriban y de ser necesario cambiarlas en el futuro poder hacerlo de forma transparente para el usuario y asi evitar links rotos.

Otros usos de las rewrite rules podrían ser redirigir a los usuarios dependiendo del lenguaje del navegador a la versión específica de nuestro sitio web más adecuada. O verificar el tipo de navegador y si detectamos que es un móvil poder enviar al usuario a la versión móvil de nuestro sitio web. Las posibilidades son infitinas, y espero poder ir contando otras formas curiosas para usar las rewrite rules.

Comentarios

15 respuestas a “¿Qué son las Rewrite Rules?”

  1. edrperez el 14/04/2008 10:17 pm

    Sin duda es una gran herramienta, en mi caso, los enlaces de uno de mis sitios serian poco atractivos para las personas sin el mod_rewrite.

  2. jcab el 15/04/2008 5:58 pm

    Muy buenos los tips. Igual hay que tener cuidado en su uso moderado que si se hace un uso excesivo en sitios muy cargados o con configuraciones peculiares puede convertirse en una cruz muy pesada.

    Saludos

  3. Dios el 16/04/2008 9:27 am

    Vaya lavado de imagen de la web, para mi gusto no ha quedado un poco fria y seria?

    Saludos

  4. edeleon el 16/07/2008 9:41 am

    Las rewrite rules son plataforma independiente, estas en especifico estan diseñadas para el servidor web Apache que puede funcionar en Windows, Mac o Linux.

  5. dehiv el 2/09/2008 2:40 pm

    Hola, muy interesante el post, pero tengo una duda:

    En el caso del rewrite para poder utilizar urls limpias pones como ejemplo esta linea:

    RewriteRule ^user/(.*)$ /mt/mt-cp.cgi?username=$1 [L]

    ¿Que pasaría si añades al final el flag R=301?:

    RewriteRule ^user/(.*)$ /mt/mt-cp.cgi?username=$1 [R=301,L]

    De esta forma lo he visto en otras web, pero segun entiendo, ¿esto lo que haría sería reescribir la url y redirigir cambiando la url del navegador??

  6. edeleon el 2/09/2008 3:24 pm

    @dehiv Gracias por tu comentario, realmente las rewrite rules son muy flexibles permitiendote hacer practicamente lo que quieras con las URL, en el caso que mencionas definitivamente la URL se reescribe y se veria en el navegador la nueva URL, ademas de indicar a los buscadores que esta URL es un cambio permanente. Con esto evitas que los buscadores bloqueen tu contenido porque pueden llegar a pensar que tienes duplicidad de paginas y te penalizan por esto.

    Todo depende de lo que necesites hacer, si necesitas hacer un cambio de URL o no, en este caso expongo este ejemplo porque en mi caso no deseaba cambiar la URL.

    Mucha suerte!

  7. dehiv el 3/09/2008 8:49 am

    @edeleon: gracias por la ayuda. Es verdad que permiten hacer multitud de cosas.. y muchas veces de varias formas distintas… yo creo que por eso precisamente a veces cuesta un poco entender los conceptos

    La cuestión es que yo quiero usar urls semanticas (aparte de por comodidad, para mejorar la indexacion y el posicionamiento en los buscadores), y según lo que me comentas, entiendo que el usar el flag R=301 sería perjudicial porque al hacerse una redirección visible, lo que finalmente quedaría sería la url normal (la NO semantica), que es lo contrario a lo que busco.

    Un saludo.

  8. manolo2111 el 18/12/2009 11:55 am

    Hola.

    Estoy intentando hacer lo siguiente:
    Tengo la url http://www.web.com/categoria

    Y con la rewrite rule debe ir a http://www.web.com/index.php?cat=categoria

    He probado con mil variantes pero no hay manera. Una de ellas es:
    RewriteRule ^(.+)$ /index.php?cat=$1

    Alguna idea?

    Muchas gracias.

  9. edeleon el 18/12/2009 12:00 pm

    @manolo2111

    Donde estas configurando las rewrite rules? has agregado la linea para encender el compilador de las reglas

    RewriteEngine On

    Tu servidor apache tiene soporte para rewrite rules?

    suerte

  10. manolo2111 el 21/12/2009 1:31 pm

    Si si, tengo ya otras rewrite rules funcionando correctamente.

    He conseguido solucionar algunas cosillas, pero ahora tengo mas dudas.

    Tengo estas 2 reglas:
    RewriteRule ^([^?][^/]+)$ ?fuse=$1&var1=$1 [NS]
    RewriteRule ^([^?]+)/(.+)$ ?fuse=$1&var1=$1&var2=$2 [NS]

    No tengo ningún problema con ellas. Funcionan correctamente tanto si pongo http://www.web.com/categoria como si pongo http://www.web.com/categoria/espuma

    El problema viene cuando añado otra regla mas para que coja 3 parámetros: http://www.web.com/categoria/espuma/blanca

    En principio debería poner debajo de la última regla:
    RewriteRule ^([^?]+)/(.+)/(.+)$ ?fuse=$1&var1=$1&var2=$2&var3=$3 [NS]

    Quedando finalmente
    RewriteRule ^([^?][^/]+)$ ?fuse=$1&var1=$1 [NS]
    RewriteRule ^([^?]+)/(.+)$ ?fuse=$1&var1=$1&var2=$2 [NS]
    RewriteRule ^([^?]+)/(.+)/(.+)$ ?fuse=$1&var1=$1&var2=$2&var3=$3 [NS]

    Pero al ponerle esta regla, algo pasa porque no me la coje. Solo me coge 1 y dos parámetros, al ponerle 3 se me va directamente al indice por defecto.

    Alguna idea?

  11. manolo2111 el 21/12/2009 1:38 pm

    Por cierto, la regla de 3 parámetros funciona si se comenta la regla de 2 parámetros, así que algo mal hay en la de 2 o algo raro pasa.

  12. edeleon el 21/12/2009 1:44 pm

    Cambia de lugar la regla 3 por la 2, de forma que primero se verifique la regla tres y sino tienes tres parametros pasara a la siguiente que es la regla con los dos parametros,

    RewriteRule ^([^?][^/]+)$ ?fuse=$1&var1=$1 [NS]
    RewriteRule ^([^?]+)/(.+)/(.+)$ ?fuse=$1&var1=$1&var2=$2&var3=$3 [NS]
    RewriteRule ^([^?]+)/(.+)$ ?fuse=$1&var1=$1&var2=$2 [NS]

    suerte

  13. manolo2111 el 21/12/2009 2:15 pm

    Hola.

    Eso no funciona, no se por que motivo tiene que ir del orden de 0, 1, 2 y 3 parámetros, en otras webs que tengo es al reves, de mas a menos.

    He conseguido solucionarlo quedando las reglas así:
    RewriteRule ^([^?][^/]+)$ ?fuse=$1&var1=$1 [NS]
    RewriteRule ^([^?][^/]+)/([^/]+)$ ?fuse=$1&var1=$1&var2=$2 [NS]
    RewriteRule ^([^?][^/]+)/([^/]+)/([^/]+)$ ?fuse=$1&var1=$1&var2=$2&var3=$3 [NS]

    El problema que tengo ahora es que también me traduce los css y los js, por lo que no me carga los estilos ni nada.

    Alguna idea de como hacer que eso no lo traduzca?

    Gracias.

  14. edeleon el 21/12/2009 2:19 pm

    Si, agregando estas condiciones

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    Le dices que si el archivo o el directorio existe dentro de la base no te aplique las reglas siguientes

    suerte

  15. tolenca el 3/02/2010 6:38 pm

    Buen dia a todos, es posible hacer que cuando se escriba la dirección de mi dominio http://www.nombre-dominio.com entonces la url se reescriba a: http://www.nombre-dominio/pagina-ejemplo.html
    Me gustaria que apenas se abra mi dominio entonces la url final sea la deseada y que quede en el navegador.
    Cual seria la sintaxis para una regla asi?

    Muchisimas gracias de antemano.

¿Quieres dejarnos tu opinión?