entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

1voto

Cómo crear una URL "amigable" desde .htaccess

Buenas, tengo una web que necesita recuperar su SEO debido a las URLs "amigables".

El caso es el siguiente, tengo la web que se encuentra en http://XXXX.com y ahora cada vez que entras en una sección de la web lo único que cambia es lo siguiente:

http://XXXX.com/?seccion=ESTO

Quiero hacer desde .htaccess que cambie el valor de dicha URL por la variable GET que obtiene y en vez de mostrar ?seccion=lo que sea sea: http://www.XXX.com/VARIABLEGET

También decir que todo viene desde una misma página, es decir, lo único que voy cambiando es el cuerpo de la web.

2 Respuestas

3votos

carlossevi Puntos63580

El contenido del archivo .htaccess creo que debería ser el siguiente:

RewriteEngine ON
RewriteRule ^(.*)$ /?seccion=$1 [L]

La explicación de la cadena de búsqueda ^(.*)$ con expresiones regulares es:
^ Principio de la cadena
(.*) Cualquier caracter cero o más veces
$ Final de la cadena

Redirige a /?seccion= seguido de la cadena.
El parámetro [L] indica que no si cumple esa regla no se busquen más reglas de redirección.

Por si te sirve, existen soluciones online para hacer pruebas con esas condiciones, yo he utilizado esta: http://htaccess.madewithlove.be/

Es importante que tengas activado el mod_rewrite de Apache en el servidor.

0voto

danielreales7 comentado

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator, [email protected] and inform them of the time the error occurred, and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.

Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.

Me sale ese error en el servidor. ¿A qué puede ser debido?

0voto

carlossevi comentado

El error 500 provocado por redirecciones suele ocurrir cuando la redirección está mal escrita y genera bucles.
Prueba con lo siguiente:

RewriteEngine ON
RewriteCond %{QUERY_STRING}  !?seccion=
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
# If the request is not for a valid link
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ /?seccion=$1 [L]

Cambios:

  1. Añadir una línea para que las peticiones que contiene el literal ?seccion= no se vuelvan a redirigir.
  2. Cambiar el * de 0 o más por el + de 1 o más caracteres, así no se redirige también el nombre del host sin ninguna cadena detrás.
  3. Añadir condiciones para que la redirección no se ejecute si es una petición directa de un directorio, fichero o link existente.

0voto

danielreales7 comentado

Ahora con esos datos me tira el siguiente error:

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator to inform of the time the error occurred and of anything you might have done that may have caused the error.

More information about this error may be available in the server error log.

0voto

carlossevi comentado

Mete el código anterior entre las etiquetas IfModule para evitar que se ejecute cuando no está activado mod_rewrite:

<IfModule mod_rewrite.c>
  ... Todo el código ...
</IfModule>

¿Te sigue dando el error?

0voto

danielreales7 comentado

Sí lo sigue dando, es extraño no?

0voto

carlossevi comentado

¿Tienes acceso al log de errores del servidor?

0voto

danielreales7 comentado

Claro, me sale esto:

RewriteCond: cannot compile regular expression '?seccion='

0voto

carlossevi comentado

Ciertamente el caracter ? es especial y debe escaparse con \:

RewriteCond %{QUERY_STRING}  !\?seccion=

0voto

danielreales7 comentado

Ahora sí, no me da error. Pero las URLs siguen mostrándose igual con ?seccion= ... no me lo cambia.

0voto

carlossevi comentado

Lo que debería pasar con el cambio es que si se accede a http://tudominio.es/misec se ve el contenido de http://tudominio.es/?seccion=misec pero no deja de funcionar el enlace "largo". Ahora deberías cambiar los enlaces para que se dirijan a la URL "amigable" y configurar en cada página la URL canónica para evitar que se considere contenido duplicado.

0voto

danielreales7 comentado

Pero claro yo lo que quiero es que sea al revés, es decir, los enlaces con http://tudominio.es/?seccion=misec se vea como http://tudominio.es/misec. Y que cambios tengo que hacer para que se produzca eso?

0voto

carlossevi comentado

No, interpreto que no quieres eso, voy a intentar explicarme. Escenario antes de tocar nada, petición que funciona en tu servidor web:

 GET /?seccion=misec HTTP/1.1
 Host: www.tudominio.es

Ahora quieres que también pueda accederse a esa misma página a través del enlace http://tudominio.es/misec, por lo que necesitas que funcione la petición:

 GET /misec HTTP/1.1
 Host: www.tudominio.es

Para ello se hace un reescritura de URL, haciendo que las peticiones a /misec se comporten como peticiones a /?seccion=misec. Eso es lo que hemos conseguido con la modificación del .htaccess.

Ahora lo que te queda es dejar de usar tu las peticiones que no te gustan (las largas), es decir, cambiar los href de tus enlaces por la URL amigable.

Extra recomendado: Configurar URL canónica para comunicar cuál de las dos URL prefieres (y así avisar de que no es contenido duplicado).
Extra adicional: Hacer una redirección de /?seccion=misec a /misec, que interpreto que es lo que creías que iba a suceder automáticamente. No lo veo imprescindible, pero puedes hacerlo.

0voto

danielreales7 comentado

Vale ahora sí lo he entendido, entonces tengo que ir cambiando los enlaces de la web por las urls "amigables".
No sé exactamente como tengo que poner los enlaces de formularios, etc. Pero gracias por la idea.

Y lo de la redirección es como me has comentado arriba no?

Muchas gracias!

0voto

danielreales7 comentado

Carlos me sale perfecto, solo una duda más, si ahora por ejemplo tengo la siguiente ruta http://www.midominio.com/miseccion y recibo otro dato más en este caso me devuelve lo siguiente: http://www.midominio.com/miseccion&pg=2, quiero que me devuelva lo siguiente: http://www.midominio.com/miseccion/pagina/2 y eso me lo hace perfecto, pero tengo que indicar en el .htaccess que entienda esa url.

¿Que es lo que debo de añadir?

Muchas gracias!

0voto

carlossevi comentado

El método debe ser el mismo, pero hace falta crear unas reglas de reescritura más complejas. Si te parece crea un pregunta derivada de ésta y pon en el enunciado el contenido del .htaccess que tienes y funciona, y la nueva necesidad para que te ayudemos a ampliarlo.

Yo no controlo en exceso las expresiones regulares (aunque intentaré solucionarlo haciendo prueba y error, así ya también aprendo) y en una nueva pregunta seguro que atraes más respuestas.

2votos

white Puntos75880

si de alguna forma quieres algo automático, suponiendo que por ejemplo tienes links que vienen de bases de datos, que son ingresadas por usuarios o algun link dinamico. puedes sobreescribir el buffer con php.

<?php
    ob_start('ob_gzhandler');

    prettyUrls();

    echo '<a href="/?seccion=posts">seccion posts</a><br />';
    echo '<a href="/index.php/?seccion=login">seccion login</a><br />';
    echo '<a href="/index.php/?seccion=registrar">seccion registrar</a><br />';

    function prettyUrls()
    {

        function rewrite($buffer)
        {
            $rules = [
                ['~(?:index\.php\/?)?\?seccion=([a-zA-Z0-9]+)~', 'seccion/$1']
            ];

            foreach($rules as $data)
            {
                $buffer = preg_replace($data[0], $data[1], $buffer);
            }

            return $buffer;
        }

        ob_start('rewrite');
    }

donde solo tendrias que agregar las reglas para el arreglo $rules y para el .htaccess

RewriteEngine ON
RewriteBase /
RewriteRule ^seccion/([a-zA-Z0-9]+)$ /?seccion=$1 [L]

0voto

Leonardo-Tadei comentado

Es muy ingeniosa la solución de sobreescribir el buffer de salida!

La probaste en combinación con otras caché de PHP, como APC o MemCache ?

También me preocuparía un poco que la regla coincida con algún otro contenido de la web, por ejemplo, la publicación de un URL... en fin: te agredecería algún comentario sobre esta técnica llevada a un ambiente de producción.

Saludos cordiales!

0voto

white comentado

hola leonardo, esta técnica la conocí hace ya un tiempo con un mod de SMF cuando no estaba tan maduro dicho mod, he probado haciendolo en varios frameworks y no me ha dado problemas, las reglas deben estar bien definidas, en SMF se juega con la base de datos y el contenido de la página. varias páginas usan este mod asi que hay gran variedad de ejemplos por la red usando esta técnica.

https://code.google.com/p/prettyurls/
http://custom.simplemachines.org/mods/?mod=636

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta