Redireccionar URL dinámica a URL estática

A todos nos gustan las URLs amigables. Por eso reescribimos las URLs dinámicas para convertirlas en URLs estáticas. Pero la reescritura de URLs tiene un problema oculto: crea dos URLs distintas que muestran el mismo contenido. Y todos sabemos que el contenido duplicado es malo. ¿Cómo podemos remediar este problema? Es más complicado de lo que parece.

Os doy un ejemplo. Digamos que tenemos una página (index.php). Se le puede pasar una variable (producto). Según nuestro ejemplo, una URL dinámica puede ser index.php?producto=25. Vamos a suponer que ya hemos introducido en el .htaccess el código necesario para reescribir estas URLs dinámicas para obtener un resultado como http://www. ejemplo.com/producto-25.html. Ahora tenemos el problema de contenido duplicado: dos URLs, una dinámica y la otra estática, que muestran el mismo contenido. Queremos redireccionar la dinámica a la estática para canonicalizarla y evitar esos problemas de contenido duplicado.

Para redireccionar la dinámica, primero tenemos que mirar a ver si la URL solicitada es index.php.

Después tenemos que comparar la petición (THE_REQUEST) con una condición a ver si coinciden. En este caso, queremos ver si la petición coincide con index.php?product=(número).

Si coinciden, le decimos al servidor que redirige [R=301] el usuario a la URL producto-(número).html. Y el .htaccess quedaría así:

# Redireccionar las URLs dinamicas a las estaticas
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9} /index.php?producto=([0-9]+) HTTP/
RewriteRule ^index.php$ /producto-%1.html? [L,R=301]

# Reescribir las URLs dinamicas para crear URLs amigables
RewriteRule ^producto-([0-9]+).html$ /index.php?producto=$1 [L]

Compartir este artículo:
  • del.icio.us
  • Google Bookmarks
  • Meneame
  • Technorati
  • BlogMemes Sp
DavidM
Acerca de DavidM
DavidM lleva trabajando en los campos del marketing por Internet y el posicionamiento en buscadores desde el año 2004. Puede ver su biografía aquí.

26 comentarios para el post “Redireccionar URL dinámica a URL estática”

  1. Comentario de Dani el 6 de Junio de 2009 a las 01:52

    No lo consigo, no hay manera,
    he seguido todos tus tutos, y nada..
    vuelvo a pegar lo que tengo en el htaccess:

  2. Comentario de Dani el 6 de Junio de 2009 a las 01:56

    El problema es que 2 páginas responden con código 200 OK. Lo correcto sería que http://www.ejemplo .com devolviera un código 200, pero tambien da 200ok http://ejemplo.com

    Cuando coloco esto: RewriteRule ^index\.(php|html|htm)$ http://www.ejemplo .com/ [R=301,L]
    se jode esto: RewriteRule ^([^/\.]+)/$/index .php?mod=$1 [L]

    y lo que he observado es que con esto: RewriteRule ^index \ .(php|html|htm)$ http://www.ejemplo.com/ [R=301,L]

    solo tengo 200ok en una pagina (como deberia ser),
    que fastidio!

  3. Comentario de Dani el 6 de Junio de 2009 a las 02:02

    no puedo pegar el codigo…
    no me deja

  4. Comentario de Dani el 6 de Junio de 2009 a las 02:13

    #AÑADIR LA BARRITA FINAL SIEMPRE

    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} !(.*)/$
    RewriteRule ^(.*)$ http://www.ejemplo.com/$1/ [R=301,L]

    #REDIRECCIONAR MODULOS

    RewriteRule ^([^/\.]+)/$ /index.php?mod=$1 [L]

  5. Comentario de Dani el 6 de Junio de 2009 a las 02:14

    #REDIRECCION CANONICA

    RewriteCond %{HTTP_HOST} ^ejemplo\.com [NC]
    RewriteRule ^(.*)$ http://www.ejemplo.com/$1 [R=301,L]

  6. Comentario de Dani el 6 de Junio de 2009 a las 03:43

    LO HE CONSEGUIDO! (casi)
    disculpas por el monólogo, pero despues de hacer pruebas durante unas horas mas.. (y ya van muchas)
    he conseguido solucionar el problema de la redireccion 301 del index sin que afecte a los modulos index.php ?mod=titulo.

    Fue algo tan “facil y absurdo” como esto:

    antes:
    RewiteRule ^([^/\.]+)/$ index.php?mod=$1 [L]

    ahora:
    RewiteRule ^([^/\.]+)/$ ?mod=$1 [L]

    muy fuerte!
    que emoción!

    GRACIAS!!!!!

  7. Comentario de Dani el 6 de Junio de 2009 a las 03:46

    ahora ya la ultima cosa, va en serio..
    no me mateis… ;)

    Apliqué las lineas de codigo que me pasastes DavidM para eliminar barras /// sobrantes,
    pero sigo teniendo el problema de que solo me funciona con las paginas php que tengo dentro de una carpeta y que no son modulares. Tiene una url como esta:

    ww. ejemplo .com/carpeta/seccion

    Si añado barras finales de más a una dirección de uno de los modulos (los que en realidad cargan en el index), entonces redirecciona a ww. ejemplo .com/seccion/?mod= seccion.

    Si solucionamos esto os hago un monumento!!

    saludos

  8. Comentario de DavidM el 9 de Junio de 2009 a las 18:19

    Si quieres que el servidor no ponga el query string (?mod=seccion) tienes que decírselo con una interrogación (?):

    RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)/{2,}\ HTTP/
    RewriteRule ^(.*)$ /%1/? [R=301,L]

  9. Comentario de Dani el 10 de Junio de 2009 a las 17:58

    PERFECTO!
    que fácil fue, era solo un interrogante!
    muchas muchas gracias,

    saludos

  10. Comentario de Dani el 23 de Septiembre de 2009 a las 22:54

    Hola,
    estoy intentando quitar la extension de las paginas pero me gustaria hacer a la vez [R=301] y no lo consigo.
    Puedo hacer la redireccion y eliminar la extension dejando la barrita solo pero cuando añado lo del [R=301] deja de funcionar. Sabrias ayudarme porfavor?

    Así me funciona: RewriteRule ^carpeta/$1.html$ /carpeta/(.*)/? [L]

    Pero para añadir el redireccionamiento permanente no lo consigo.. he provado varias cosas.. una es esta de aqui abajo, pero no funciona porque redirige a la misma pagina como en un bucle:

    RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /carpeta/(.*)\.html\ HTTP/
    RewriteRule ^carpeta/(.*)\.html$ /carpeta/%1/? [R=301,L]

    gracias!

  11. Comentario de DavidM el 24 de Septiembre de 2009 a las 08:41

    Prueba esto…

    # Redirigir las URLs antiguas a las nuevas (sin la barra al final).
    RewriteCond %{REQUEST_URI} ^/carpeta/([\.]+).html$
    RewriteRule ^carpeta/([^\.]+)\.html$ /carpeta/$1? [R=301,L]

    # Si alguien intenta ponerle una barra, quitarla.
    RewriteRule ^carpeta/([^/]+)/$ /carpeta/$1? [R=301,L]

    # Cuando se solicita /carpeta/ más cualquier cosa menos una barra, mostrar el contenido del fichero.
    RewriteCond %{REQUEST_URI} ^/carpeta/([^/]+)$
    RewriteRule ^carpeta/([^/]+)$ /carpeta/%1.html? [L]

  12. Comentario de Dani el 24 de Septiembre de 2009 a las 21:56

    Gracias David!
    pero no me ha funcionado…
    También tengo en el .htaccess unas lineas donde le digo que añada la barra final, una y solo una, a todo.
    Y he pensado que quizas era eso, pero no. Sigue sin funcionar.
    De todos modos, esto que tu me pones de quitarle la barrita final me gusta, porque como solo se lo hago a los de esta carpeta pues ya me va bien..
    Quiero decir que lo de ponerle barrita a todo me parecia fantástico hasta que el otro dia redireccioné un pdf al que tb se le añade la barrita y entonces nunca encuentra el documento porque acaba en .pfd/
    Por eso digo, que tu ejemplo aplicado así me gusta.. porque soluciona el tema del pdf tb quizas..
    como me enrollo.. ¿se ha entendido algo?

    Saludos!

  13. Comentario de Dani el 24 de Septiembre de 2009 a las 23:45

    Bueno, funcionar si que funciona pero se sigue podiendo acceder a la misma página con extension .html o sin ella.
    El tema es que estas paginas no son dinamicas, pero queria darle el mismo look a la url que las dinamicas, es decir sin extensión y con barrita y asegurandome el 301.
    Lo he probado de 100 formas, ¿quizas no se puede hacer?

    Lo que me has pasado lo he adaptado a mi caso, añadiendo barritas finales siempre. Porque como te decía añadí esto para poner siempre barrita a todo:

    #AÑADIR LA BARRITA FINAL SIEMPRE

    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} !(.*)/$
    RewriteRule ^(.*)$ http://www. posicionapro .com/$1/ [R=301,L]

    # SI HAY MAS DE UNA BARRITA PONER SOLO UNA

    RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)/{2,}\ HTTP/
    RewriteRule ^(.*)$ /%1/? [R=301,L]

    Pero mi pregunta es: ¿Hay manera de poder especificar que a los pdf’s no los trate igual que al resto de paginas y no les añada la barra final?

    gracias!

  14. Comentario de DavidM el 25 de Septiembre de 2009 a las 12:50

    Te pido perdón. Puse mal el código. Lo he corregido. (Creo). :)

    # Redirigir las URLs antiguas a las nuevas (sin la barra al final).
    RewriteRule ^carpeta/([^\.]+)\.html$ /carpeta/$1? [R=301,L]

    # Si alguien intenta ponerle una barra, quitarla.
    RewriteRule ^carpeta/([^/]+)/$ /carpeta/$1? [R=301,L]

    # Cuando se solicita /carpeta/ más cualquier cosa menos una barra, mostrar el contenido del fichero.
    RewriteCond %{REQUEST_URI} ^/carpeta/([^/]+)$
    RewriteRule ^carpeta/([^/]+)$ /carpeta/%1.html? [L]

    Y si eso no funciona, puede que tengas que sustituir ([^/]) con algo así como ([a-zA-Z0-9-]):

    # Redirigir las URLs antiguas a las nuevas (sin la barra al final).
    RewriteCond %{REQUEST_URI} ^/carpeta/([\.]+).html$
    RewriteRule ^carpeta/([a-zA-Z0-9-]+)\.html$ /carpeta/$1? [R=301,L]

    # Si alguien intenta ponerle una barra, quitarla.
    RewriteCond %{REQUEST_URI} ^/carpeta/([^/]+)/$
    RewriteRule ^carpeta/([a-zA-Z0-9-]+)/$ /carpeta/$1? [R=301,L]

    # Cuando se solicita /carpeta/ más cualquier cosa menos una barra, mostrar el contenido del fichero.
    RewriteCond %{REQUEST_URI} ^/carpeta/([^/]+)$
    RewriteRule ^carpeta/([a-zA-Z0-9-]+)$ /$1.php? [L]

  15. Comentario de Dani el 25 de Septiembre de 2009 a las 19:53

    Gracias David!
    me hace lo mismo.. no funciona, hace bucle y da error por redirigir una pagina que a la vez reidirege a la msima y así hasta que peta..

    Yo lo de la barrita lo he quitado.
    Las lineas de codigo en problematicas son estas:

    # Redirigir las URLs antiguas a las nuevas.
    RewriteRule ^carpeta/([a-zA-Z0-9-]+)\.([a-zA-Z0-9-]+)$ /carpeta/$1/? [R=301,L]

    Lo demas funciona bien, pero como digo, es imposible hacer el 301 por lo visto.. la identifica como la misma pagina.. y hace bucle de redireccionamento. Aqui ya ves que he probado tb a separar la extension es una variable tb para poder hacer uso luego solo del $1 pero ni aun así me funciona, hace lo mismo.. un bucle..
    parecido a como yo cuando escribo.. ;)

    Saludos!

  16. Comentario de Joranve el 6 de Febrero de 2010 a las 02:57

    Estuve investigando sobre esto y logré hacer que en la URL no aparezca ninguna extension es decir que quede algo como esto:
    http://www.mipaginaweb.com/pagina/1titulo-pagina

    La pagina dinamica está en la url: http://www.mipaginaweb.com/index.php?id=1

    en el .htaccess coloqué lo siguiente:
    RewriteRule pagina/(.*)$ /index.php?id=$1

    Se preguntaran porque pongo en la direccion “1titulo-pagina”
    bueno el 1 es el valor de variable “id” del php, despues de ese valor se puede escribir lo que uno desee

    Bueno espero que les sea de utilidad mi aporte.

  17. Comentario de Sergio Monge el 27 de Febrero de 2010 a las 17:01

    Hola:

    Tengo un problema con una redirección web en mi blog. Intento redirigir neuromarca.com/blog a neuromarca.com/categoria/blog. En principio no hay problema pero resulta que la orden redirige un montón de otras páginas que empiezan por neuromarca.com/blog (http://neuromarca.com/blog/noticias-del-mercado-del-neuromarketing/) pero que no quiero redirigir.

    ¿Hay alguna manera de redirigir sólo esa dirección y no las que empiezan igual?

  18. Comentario de DavidM el 27 de Febrero de 2010 a las 18:00

    Hola Sergio. Falta el símbolo del dólar ($) al final de la regex.

    RewriteRule ^neuromarca\.com/blog$ /neuromarca.com/categoria/blog [R=301,L]

    Pruéba eso a ver si te soluciona el problema.

  19. Comentario de Sergio Monge el 27 de Febrero de 2010 a las 18:09

    Me temo que sigue sin funcionar. No parece que reconozca esa orden. He probado lo que has puesto y también con:

    RewriteRule ^neuromarca\.com/blog$ /neuromarca.com/categoria/blog [R=301,L]

    Pero nada.

  20. Comentario de Sergio Monge el 27 de Febrero de 2010 a las 18:10

    Quería decir:

    Me temo que sigue sin funcionar. No parece que reconozca esa orden. He probado lo que has puesto y también con:

    RewriteRule ^neuromarca\.com/blog$ http://neuromarca.com/categoria/blog [R=301,L]

    Pero nada.

  21. Comentario de DavidM el 28 de Febrero de 2010 a las 00:53

    ¡Doh! No sé en qué estaba pensado cuando te he contestado. Quería decir:

    RewriteRule ^blog$ /categoria/blog [R=301,L]

  22. Comentario de Sergio Monge el 28 de Febrero de 2010 a las 10:07

    Gracias por intentarlo pero me parece que tampoco es así.

  23. Comentario de DavidM el 28 de Febrero de 2010 a las 19:48

    Parece que has encontrado la solución, ¿no? Visito http://neuromarca.com/blog y me redirige a http://neuromarca.com/categoria/blog/

    ¿Cuál era la solución?

  24. Comentario de Sergio Monge el 28 de Febrero de 2010 a las 23:16

    ¡Ostras! Tenías razón. No sé como lo había mirado y pensaba que no funcionaba, pero si que funciona.

  25. Comentario de DavidM el 1 de Marzo de 2010 a las 10:15

    Fantástico. Si quieres redireccionar tanto “/blog” como “/blog/”, pruéba esto:

    RewriteRule ^blog(\/?)$ /categoria/blog [R=301,L]

  26. Comentario de Sergio Monge el 1 de Marzo de 2010 a las 10:34

    Que bruto soy. Había añadido al htaccess:

    RewriteRule ^blog/$ /categoria/blog [R=301,L]

Escribe un comentario

Entradas realcionadas

  1. URL Rewrite Rule Generator para apache mod_rewrite
  2. Canonicalizacion
  3. Como quitar la barra final de las URLs con htaccess y mod_rewrite
  4. Como borrar filas de varias tablas en MySQL