¿Cómo implemento la reescritura de URL en mi archivo .htaccess?

17

Me gustaría hacer una reescritura de URL (¿Por qué? Vea esta pregunta ) para que en lugar de que los usuarios vean direcciones como

labouseur.com/course-compilers.html 

en cambio, pueden ver y usar simplemente

labouseur.com/course-compilers

(Aún mejor, tal vez debería reestructurar eso para que sean cursos / compiladores).

Estoy usando un servicio de alojamiento compartido basado en Linux para mi sitio web, por lo que no tengo control administrativo del servidor, pero sí tengo control sobre .htaccess. Las referencias que he leído en línea me parecieron poco claras, así que estoy buscando un poco de claridad y consejos aquí.

Alan
fuente
Tenga en cuenta que esto no es algo que solo hace en la configuración del servidor (.htaccess). El primer paso importante es cambiar realmente las URL en su aplicación, de lo contrario terminará con muchas redirecciones innecesarias (o contenido duplicado).
MrWhite

Respuestas:

13

En realidad, podría eliminar .html de los archivos en su servidor y establecer la configuración en htaccess para que se sirvan como archivos html, pero eso probablemente no sea lo que está buscando.

Hacer esto :

RewriteEngine on
# Check this condition to ensure that it's not a directory.
RewriteCond %{REQUEST_FILENAME} !-d
# Check this condition to ensure that there's a file there
RewriteCond %{REQUEST_FILENAME}\.html -f
# Replace html with your file extension, eg: php, htm, asp
RewriteRule ^(.*)$ $1.html
Rizwan Kassim
fuente
Aquí hay más complejidad, especialmente si le preocupan los problemas de contenido duplicado. Con la regla anterior, aún se podrá acceder a sus páginas desde las URL antiguas.
JasonBirch
3

Primero, asegúrese de que apache tenga el módulo y que esté permitido en archivos .htacces, luego agregue:

RewriteEngine on

# Rewrite rules
RewriteRule ^/myoldsubfolder/(.*) /newfolder/$1 

Tu ejemplo requeriría

RewriteCond %{REQUEST_URI} !-d
RewriteCond %{REQUEST_URI}\.html -f
RewriteRule ^/(([a-zA-Z0-9_]+)/?)$ /$1.html

Para una estructura de directorio de un solo nivel y

RewriteRule ^/(([a-zA-Z0-9_]+)/?)+$ /$1.html

Para una estructura multinivel.

Pero ten cuidado

Si tienes la estructura

/site/.htaccess
/site/subfolder/.htaccess
/site/subfolder/cats/.htaccess

Las reglas de reescritura en los .htaccessarchivos secundarios serán relativas a su carpeta principal y puede entrar en algunas situaciones de bucle de reescritura desordenadas . ¡Asegúrate de usar RewriteCondpara evitar que sucedan si puedes!

Aiden Bell
fuente
¿Te importa entrar en más detalles sobre ese último punto (usando RewriteCond para detener los bucles)?
Travis Northcutt
2

Además de las respuestas anteriores, se puede usar

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^([\w-]+)$ $1.html [L]

([\w-]+) Permite letras, dígitos con un guión (-).

(.*) reescribirá cada solicitud independientemente, lo que puede ser impotente en otras reglas siguientes que causen un error interno del servidor al acceder.

Abhishek Gurjar
fuente
Su RewriteRule patrón es una mejora sobre la respuesta aceptada para el ejemplo específico dado en la pregunta, sin embargo, no coincidirá con el caso más general cuando hay más de un segmento de ruta, por ejemplo. /path/to/course-compilers. Incluya la Lbandera para disminuir el impacto en las siguientes reglas. Si bien el (.*)patrón es innecesariamente general, es poco probable que cause problemas graves, debido a la condición de que el archivo existe.
MrWhite
1

No tiene que usar un archivo .htaccess para lograr esto. Simplemente estructura tus archivos en directorios, y en lugar de usar "labouseur.com/course-compilers.html", simplemente nombra el archivo index.html y colócalo en un directorio llamado "compiladores del curso". Luego, cuando apunta a ese directorio, el índice se sirve de forma predeterminada, pero no se mostrará en la URL. Así que podría escribir sus enlaces como "labourseur.com/course-compilers" y todo estará bien.

No se requiere acceso.

Joel Glovier
fuente