
El archivo .htaccess, ese gran desconocido para muchos desarrolladores. Y para otros, sabiendo que existe, prefieren ni tocarlo por desconocimiento de como funciona.
Es verdad que no es imprescindible saber manejarlo para crear un web y menos si utilizas un CMS. Pero la cantidad de posibilidades que ofrece, principalmente para el SEO y la seguridad de sitio web, hace que sea vital que aprendas como funciona.
Primero, ¿como funciona?
Htaccess (Hypertext access) es un archivo compatible con servidores Apache, de configuración de directorios del servidor. Por ejemplo, redirigir a otra dirección web, personalizar páginas de error, proteger directorios o archivos con contraseña, bloquear IPs, cambiar a HTTPS, etc…
El archivo es hederitario, por lo que afecta al directorio donde se encuentra y todos los subdirectorios del mismo. Por eso, recomiendo que lo pongais en el directorio raíz.
Es importante familiarizarse con la sintaxís u asegurarse de escribir correctamente el código. Un espacio en blanco de más o un error de escritura pueden provocar un error fatal en nuestro sitio web. Por eso, también os recomiendo hacer una copia del archivo antes de hacer cambios. Para hacer comentarios utilizamos «#». Si el comentario es de varias líneas, lo ponemos al principio de cada línea:
# Este es un comentario en htaccess # que sigue por esta segunda linea
Otras reglas de escritura en .htaccess:
[F] Forbidden (prohibido): le dice al servidor que devuelva al cliente un 403 Forbidden.
[L] Last rule (última regla): le dice al servidor que deje de hacer rewrite una vez se procese la directiva anterior.
[N] Next (siguiente): le dice a Apache que vuelva a ejecutar el rewrite hasta que todas las directivas de rewrite se hayan ejecutado.
[G] Gone (ido): le dice al servidor que entregue el mensaje de estado Gone (no longer exists).
[P] Proxy: le dice al servidor que gestione las peticiones mediante mod_proxy
[C] Chain (cadena): le dice al servidor que encadene la regla actual con la anterior.
[R] Redirect (redirigir): le dice a Apache que lance una redirección, haciendo que el navegador muestre la URL re-escrita/modificada.
[NC] No Case: define cualquier argumento al que esté asociado como no afectado por mayúsculas-minúsculas, o sea, como case-insensitive, “NC” = “No Case”.
[PT] Pass Through (pasar a través): le dice a mod_rewrite que pase la URL re-escrita de nuevo a Apache para que la procese de nuevo.
[OR] Or (o): especifica una lógica “o” que enlaza dos expresiones para que si una u otra se cumple se aplique la regla asociada a la misma.
[NE] No Escape: le dice al servidor que redistribuya la salida sin escapar caracteres.
[NS] No Subrequest (sin petición subyacente): le dice al servidor que se salte la directiva si hay peticiones internas subyacentes.
[QSA] Append Query String: insta al servidor a que añada una cadena de petición al final de la expresión (URL).
[S=x] Skip (saltar): le dice al servidor que se salte las siguientes “x” reglas si encuentra alguna coincidencia..
[E=variable:value] Environmental Variable (variable del entorno): le dice al servidor que establezca la variable del entorno (“variable”) al valor definido (“value”).
[T=MIME-type] Mime Type: declara el tipo mime del recurso al que está dirigido.
[] Especifica una clase de carácter, por el que cualquier carácter dentro de los corchetes se considerará una coincidencia, por ejemplo en [xyz], con x, y o z.
[]+ Clase de carácter en el que cualquier combinación de elementos dentro de los corchetes se considera una coincidencia; por ejemplo [zyz]+ considerará una coincidencia cualquier número de equis, y griegas o zetas, o cualquier combinación de estos caracteres.
[^] Especifica que no está dentro de una clase de carácter; por ejemplo, [^xyz] considerará una coincidencia cualquier carácter que no sea ni x, ni y, ni z.
[a-z] Un guión (-) entre dos caracteres dentro de corchetes ([]) define un rango de caracteres; por ejemplo [a-zA-Z] se refiere a todas las letras en mayúsculas y minúsculas de la a a la z.
a{n} Especifica un número exacto (n) del carácter precedente; por ejemplo x{3} se refiere exactamente a tres x.
a{n,} Especifica un número no o más del carácter precedente; por ejemplo x{3,} se refiere a tres x o más.
a{n,m} Especifica un rango de números, entre n y m, del carácter precedente; por ejemplo x{3,7} se refiere a tres, cuatro, cinco, seis o siete x.
() Se utiliza para agrupar juntos un grupo de caracteres, considerándolos como una sola unidad; por ejemplo (ayuda)?wordpress se referirá a wordpress, ya sea con o sin el prefijo ayuda.
^ Indica el comienzo de una cadena de prueba de una expresión regular (regex); por ejemplo, empezar el argumento con el carácter anterior.
$ Indica el fin de una cadena de prueba de una expresión regular; por ejemplo, terminar el argumento con el carácter anterior.
? Declara opcional el carácter precedente; por ejemplo cachopo? valdrá para cachopo y cachopos, mientras que cachopo(s)? se referirá tanto a cachopo como a cachopos; por ejemplo x? se refiere a ninguna o una x.
! Declara negación; ejemplo “!cadena” valdrá para todo menos para “cadena”.
. Un punto (o periodo) indica cualquier carácter arbitrario simple.
– Indica que “no se” haga rewrite de la URL, como en “…dominio.es.* – [F]”.
+ Se refiere a uno o más caracteres del carácter precedente; por ejemplo, G+ se refiere a una o más Gs, mientras que simplemente “+” vale para uno o varios caracteres de cualquier tipo.
* Se refiere a cero o más de los caracteres precedentes; por ejemplo, puedes usar “.*” como comodín.
| Declara un operador lógico “or”; por ejemplo, (x|y) vale para x o y.
\ Escapa caracteres especiales ( ^ $ ! . * | ); por ejemplo, usa “\.” para indicar/escapar un punto literalmente.
\. Indica un punto literal (escapado).
/* Cero o más barras.
.* Cero o más caracteres arbitrarios.
^$ Define una cadena vacía.
^.*$ El patrón estándar para que valga cualquier cadena.
[^/.] Define un carácter que no es ni una barra ni un punto.
[^/.]+ Define cualquiera números o caracteres que no contengan ni barra ni punto.
http:// Esta es una declaración literal — en este caso la cadena de caracteres literal “http://”.
^domain.* Define una cadena que comienza con el término “domain”, probablemente precedido por cualquier número de caracteres.
^domain\.com$ Define la cadena exacta “domain.com”.
-d Comprueba si la cadena es un directorio existente.
-f Comprueba si la cadena es un archivo existente.
-s Comprueba si el archivo de la cadena contiene un valor que no sea cero.
Después de esto, os dejo algunos de los trucos más utilizados en htaccess. Simplemente copiad el código y sustituir las url por las de vuestro sitio web. Para que estas directrices funcionen tu servidor tiene que tener instalado el mod_rewrite. Lo podemos comprobar en el archivo httpd.config, aunque no debe preocuparnos ya que viene instalado por defecto en la mayoría de servidores Apache.
Cambiar página establecida por defecto
Cuando un usuario carga nuestro sitio web poniendo el dominio, los servidores intentan cargar una página por defecto. Esto podría bastar si la nombraramos index (index.html, index.php, etc…)
Pero también podemos forzar a que cargue otra página con otro nombre. Por ejemplo, inicio.html. Además podemos poner varias opciones porque como dije antes, estas directrices son hederitarias y afectan a todos los directorios. Solo hace falta poner esta linea:
DirectoryIndex inicio.html
Forzar urls con www
Tal vez nos interese que Google no trate nuestra web con www y sin www como páginas diferentes y reparta importancia entre ambas. Para eso forzamos una de las dos opciones. Cambiamos la dirección web por la nuestra:
RewriteEngine on RewriteCond %{HTTP_HOST} ^midominio\.com [NC] RewriteRule ^(.*)$ http://www.midominio.com/$1 [L,R=301,NC]
Forzar urls sin www
RewriteEngine on RewriteCond %{HTTP_HOST} ^www\.midominio\.com [NC] RewriteRule ^(.*)$ http://midominio.com/$1 [L,R=301]
Páginas de error personalizadas
Todos conocemos las clásicas páginas de error de servidor como el error 404 (Página no encontrada), pero la que viene por defecto es muy pobre y muy cutre. Podemos hacer una propia personalizada e indicarle al servidor que rediriga a nuestra página cuando de dicho error:
ErrorDocument 400 /directorio/error-400.html ErrorDocument 401 /directorio/error-401.html ErrorDocument 403 /directorio/error-403.html ErrorDocument 404 /directorio/error-404.html ErrorDocument 500 /directorio/error-500.html
Redireccionamientos 301
Imagínate que tenemos una página muy visitada pero queremos borrarla, sustituirla o cambiar la url. Sino queremos causar un problema a los usuarios que tuvieran guardada la dirección antigua, podemos utilizar Redirect 301 poniendo la url antigua y a la cual queremos redirigir:
Redirect 301 /pagina_antigua.html http://www.midominio.com/nueva_pagina.html Redirect 301 /pagina_antigua_2.html http://www.midominio.com/directorio/
Si queremos redireccionar todo el sitio:
Redirect 301 / http://nuevo-dominio.com/
Bloquear por IPs
Podemos bloquear el acceso a nuestro sitio por completo. Si por ejemplo lo estamos construyendo, lo hacemos desaparecer de internet:
Deny from all # O podemos bloquearlo parcialmente. Solo para ciertas IPs. Sustituye "xxx.xxx.xxx.xxx" por la IP correspondiente Order deny, allow Allow from All Deny from XXX.XXX.XXX.XXX Deny from XXX.XXX.XXX.XXX # O bloquearlo para todos menos para ciertas IPs: Order deny, allow Deny from All Allow from XXX.XXX.XXX.XXX
Proteger archivos y directorios con contraseña
Para ello necesitamos crear un archivo llamado.htpasswd y guardarlo en algún subdirectorio para uso privado. Declaramos el usuario en este archivo:
$ htpasswd -c /home/privado/.htpasswd nombre_usuario
Y ahora con .htaccess declaramos que archivos o directorios queremos proteger:
AuthName "Zona Protegida" AuthType Basic AuthUserFile /home/privado/.htpasswd <Files "archivo-protegido.pdf"> Require valid-user </Files>
Denegar acceso a archivos comprometidos
Puede que tengamos archivos delicados que guarden contraseñas o manejen directrices importantes de la web como .htaccess o .htpasswd. Si queremos que no caiga en malas manos ponemos el siguiente código:
<FilesMatch $^*(.)^ini|log|htpasswd|htaccess> Order allow,deny Deny from all Satisfy All </FilesMatch>
Habilitar compresión deflate o Gzip
# Compresión deflate por tipo de archivo <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE text/javascript AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/atom_xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript AddOutputFilterByType DEFLATE application/x-shockwave-flash </IfModule> #Compresión por Gzip <IfModule mod_gzip.c> mod_gzip_on Yes mod_gzip_dechunk Yes mod_gzip_item_include file\.(html?|txt|css|js|php|pl)$ mod_gzip_item_include handler^cgi-script$ mod_gzip_item_include mime^text/.* mod_gzip_item_include mime^application/x-javascript.* mod_gzip_item_exclude mime^image/.* mod_gzip_item_exclude rspheader^Content-Encoding:.*gzip.* </IfModule>
Activar cabecera Expires HTTP
Con la cabecera HTTP Expires podemos limitar el tiempo en cada tipo de archivo en el que el navegador tira de la caché y vuelve a descargarlo del servidor. Es importante diferenciar entre archivos más estáticos (CSS, JS, imágenes, etc…), que tienen menos actualizaciones y archivos más dinámicos como HTML o PHP:
<IfModule mod_expires.c> ExpiresActive on ExpiresDefault "access plus 1 month" # CSS ExpiresByType text/css "access plus 1 year" # Archivos relacionados con AJAX y Web Sockets ExpiresByType application/json "access plus 0 seconds" ExpiresByType application/xml "access plus 0 seconds" ExpiresByType text/xml "access plus 0 seconds" # Favicon ExpiresByType image/x-icon "access plus 1 week" # Componentes HTML (HTCs) ExpiresByType text/x-component "access plus 1 month" # HTML ExpiresByType text/html "access plus 0 seconds" # JavaScript ExpiresByType application/javascript "access plus 1 year" # Manifest ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds" ExpiresByType text/cache-manifest "access plus 0 seconds" # Fotos, vídeos y audio ExpiresByType audio/ogg "access plus 1 month" ExpiresByType image/gif "access plus 1 month" ExpiresByType image/jpeg "access plus 1 month" ExpiresByType image/png "access plus 1 month" ExpiresByType video/mp4 "access plus 1 month" ExpiresByType video/ogg "access plus 1 month" ExpiresByType video/webm "access plus 1 month" # Canales RSS y Atom ExpiresByType application/atom+xml "access plus 1 hour" ExpiresByType application/rss+xml "access plus 1 hour" # Fuentes web ExpiresByType application/font-woff "access plus 1 month" ExpiresByType application/vnd.ms-fontobject "access plus 1 month" ExpiresByType application/x-font-ttf "access plus 1 month" ExpiresByType font/opentype "access plus 1 month" ExpiresByType image/svg+xml "access plus 1 month" </IfModule>
Desactivar cabecera ETag HTTP
Recomiendo desactivar esta cabecera ya que algunos navegadores o proxys pueden ignorarla. Y así forzamos el uso de cabeceras «Cache-control» o «Expires» citado anteriormente:
<IfModule mod_headers.c> Header unset ETag </IfModule> FileETag None
Forzar descarga de archivos en vez de mostrarlos
Tan solo tenemos que sustituir «.pdf» por la extensión que queramos para que esos archivos se descarguen automáticamente:
<Files *.pdf> ForceType application/octet-stream Header set Content-Disposition attachment </Files>
Forzar uso de codificación UTF-8
# Forzar la codificación UTF-8 para html y texto plano AddDefaultCharset utf-8 # Forzar la codificación UTF-8 otros tipos de archivos AddCharset utf-8 .css .js .json .rss .xml
Eliminar extensiones html en las urls
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^([^\.]+)$ $1.html [NC,L]
Evitar listado del contenido de un directorio
Options All -Indexes
Evitar hotlinking
El hotlink es el mal uso de nuestra web por algunos usuarios que enlazan imágenes o videos nuestros en sus webs utilizando nuestro ancho de banda. Con este código podemos evitarlo y mostrar una imagen de aviso:
# Evitar el hotlinking y mostrar imagen alternativa <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http://(www\.)?midominio\.es/.*$ [NC] RewriteRule .*\.(gif|jpg)$ http://www.midominio.es/norobeshombre.jpg [R,NC,L] </IfModule>
Normalmente en un servidor Apache ya viene por defecto el archivo htaccess que podemos manipular. Sino, podemos crearlo con un block de notas mismamente y nombrandolo .htaccess (sin la extensión .txt).
Comentarios recientes