htaccess (Acceso de Hiper-Texto) es un archivo de texto que Apache usa para crear reglas sobre los directorios y archivos. Tiene múltiples funciones y en lo personal me parece una herramienta sumamente interesante pero complicada de usar.
El servidor Apache tiene un módulo llamado mod_rewrite que permite redirigir y modificar la URL solicitada basada en reglas expresada en expresiones regulares PCRE. Coloque estos comandos en un archivo texto plano de nombre .htaccess en la raíz del sitio web.
Proporciona una forma flexible y poderosa de manipular URL usando un número ilimitado de reglas. Cada regla puede tener un número ilimitado de condiciones de regla adjuntas, para permitirle reescribir URL en función de variables de servidor, entorno, encabezados HTTP o marcas de tiempo.
De forma general se puede decir que las directivas en el .htaccess se componen de tres partes: el tipo de directiva (Options, RewriteCond), los parámetros de la directiva y por último el final de cada línea en que se pueden agregar modificaciones adicionales.
Directiva | Descripción |
---|---|
DirectoryIndex | Cambiar la página por defecto. |
Redirect | Redireccionar el tráfico web. |
? | Limitar los tipos de archivos que pueden subirse a un directorio. |
RewriteCond | Define una condición bajo la cual tendrá lugar la reescritura. |
RewriteRule | Define reglas para el motor de reescritura. |
RewriteOptions | Establece algunas opciones especiales para el motor de reescritura. |
RewriteBase | Establece la URL base para reescrituras por directorio. |
RewriteEngine | Habilita o deshabilita el motor de reescritura en tiempo de ejecución. on|off. |
RewriteMap | Define una función de mapeo para la búsqueda de claves. |
Se puede usar esta directiva para cambiar la página por defecto (el orden es importante).
DirectoryIndex inicio.html index.htm index.html index.php
Redirect antiguo nuevo
Redirect /antiguo.php http://sitio.com/nuevo.php Redirect www.sitio.com https://sitio.com redirect 301 / https://domain.com/ redirect 301 /archivo.html http://www.domain.com/denegado.php
Redirect permanent antiguo nuevo
Redirect permanent / http://www.domain.com/
Para redirigir en función de lo que se ingrese.
RewriteEngine on RewriteCond patrón condición [modificador] RewriteRule patrón sustitucion [modificador]
RewriteCond %{HTTP_USER_AGENT} (iPhone|Blackberry|Android) [NC]
Esta es el verdadero caballo de batalla de la reescritura. La directiva puede ocurrir más de una vez y cada instancia define una sola regla de reescritura. El orden en que se definen estas reglas es importante porque este sera el orden en que se aplicarán en tiempo de ejecución.
RewriteRule patrón sustitucion [modificador]
Primero se comparar el patrón con la parte de la URL despues de nombre del HOST %{HTTP_HOST} y puerto %{SERVER_PORT} pero antes de la cadena de consulta. Ej: app1/index.php
RewriteRule ^/games /usr/local/games/web //Crea un alias RewriteRule ^/games$ http://sitio.com/juegos.php [R] //Ruta absoluta RewriteRule ^/games/(.*)$ http://sitio.com/$1/index.php [R] //$1 se reemplaza con primer () RewriteRule ^(.*)$ http://www.nueva.com/$1 [R=301,L]
Si hay más de una expresión entre paréntesis, estarán disponibles en el orden en las variables $1, $2, $3, y así sucesivamente.
301 (Moved Permanently) esta y todas las peticiones futuras deberían ser dirigidas a la URL dada.
Se puede habilitar la compresión de datos inherente de PHP para ahorrar ancho de banda.
<ifmodule mod_php4.c> php_value zlib.output_compression 16386 </ifmodule>
Por defecto, el servidor Apache muestra una página de error 404 (File Not Found), cuando nuestros visitantes acceden a una página que en el momento no existe. Sin embargo, la página por defecto es poco amigable y no deja una buena impresión. Por lo que, podríamos crear una página especial, a la cual redirigir al cliente cada vez que se produce el error 404.
ErrorDocument error pagina
Código | Descripción | |
---|---|---|
400 | Bad Request | El servidor no procesará la solicitud, porque no puede, o no debe, debido a algo que es percibido como un error del cliente (ej: solicitud malformada, sintaxis errónea, etc). La solicitud contiene sintaxis errónea y no debería repetirse. |
401 | Unauthorized | Similar al 403 (Forbidden), pero específicamente para su uso cuando la autentificación es posible pero ha fallado o aún no ha sido provista. |
403 | Forbidden | La solicitud fue legal, pero el servidor rehúsa responderla dado que el cliente no tiene los privilegios para realizarla. En contraste a una respuesta 401 No autorizado, autenticarse previamente no va a cambiar la respuesta. |
404 | Not Found | Recurso no encontrado. Se usa cuando el servidor web no encuentra la página o recurso solicitado. |
429 | Too Many Requests | Hay muchas conexiones desde esta dirección de internet. |
ErrorDocument 404 /tiburon.php
Cuando un directorio no tiene la página de index, cualquier visitante puede observar los archivos contenidos en el directorio y navegar a través de ellos.
Options All -Indexes
Para forzar la conexion SSL en todo el sitio con ModRewrite.
RewriteEngine On RewriteCond %{HTTPS} !=on RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
Si queremos forzar SSL y quitar añadir el www:
RewriteEngine On RewriteCond %{HTTPS} !=on RewriteCond %{HTTP_HOST} !^www\..+$ [NC] RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Los parámetros son expresiones regulares o patrones de cadenas de textos que se definen usando símbolos como el ^ para indicar el inicio, el $ para señalar el final, ? para un carácter opcional (un comodin), el * para varios caracteres opcionales (comodines).
Parámetro | Descripción | Ejemplo |
---|---|---|
. | Coincide con cualquier carácter. Comodín. | c.t puede ser: cat, cot, cut, etc |
+ | Repite el carácter anterior una o más veces. | a+ puede ser: a, aa, aaa, etc |
* | Repite el carácter anterior cero o más veces. | a* puede ser: mismo que a+ pero también vacío. |
? | Hace el carácter opcional. Solo uno. | s?to puede ser: sato, seto, sito, etc |
\ | Escapa el siguiente carácter. | sitio\.com, nota que es específicamente el punto. |
() | Agrupa varios caracteres en una sola unidad y captura una coincidencia para usar en una referencia. | (abc)+ igual que a+ pero se aplica al grupo. |
[] | Una clase de personaje: coincide con uno de los personajes | c[aou]t puede ser: cat, cot o cut. |
(.*) cualquier expresión. .* indica cero o más caracteres arbitrarios. /* indica cero o más "/".
Parámetro | Descripción |
---|---|
^ | marca el inicio del argumento. |
$ | marca el fin del argumento. |
^$ indica un "empty string". ^.*$ indica cualquier cosa.
Parámetro | Descripción |
---|---|
# | Se ignora la línea. Es un comentario. |
[]+ | se usa para hacer combinaciones. |
[^] | excluye los carácteres dentro del paréntesis, de los resultados. Ejemplo [^xyz]. |
a{n} | especifica el número exacto del carácter que le precede. |
a{n,} | especifica el número "o más" del carácter que le precede. |
a{n,m} | especifica un rango entre n y m. Ejemplo: x{4,7} = resulta 4,5,6 o 7 caracteres 'x'. |
[a-z] | solamente letras. |
[a-z]{3} | palabra de 3 caracteres. |
[a-z]{1,10} | palabra de entre 1 y 10 caracteres. |
[0-9] | solamente números. |
[0-9]{4} | número de 4 dígitos. |
! | Negar expresion. Es decir, se considerará que una cadena ha coincidido solo si no coincide con la expresión. |
- | instrucción “not to”. |
| | declara "or". Ejemplo (x|y) resulta "x" o "y". |
\ | para leer caracteres especiales. Ejemplo “\.” indica literalmente un punto. |
[^/.]+ | define, ningún número de carácter que sea "/" ni ".". |
http:// | es literalmente “http://”. |
^sitio.* | define una cadena que comienza con la palabra "sitio" y continúa con cualquier número de caracteres. |
^sitio\.com$ | define exactamente “sitio.com”. |
-d | prueba si la cadena es un directorio existente. |
-f | prueba si la cadena es un archivo existente. |
-s | prueba si el archivo en el string no tiene valor cero. |
Los valores que aparecen entre corchetes al final de cada línea son modificadores o acciones. Por ejemplo, para RewriteCond se comun usar [NC] para indicar que en la directiva no debe distinguirse entre mayúsculas y minúsculas (no case), u [OR] para indicar que la expresión actual debe interpretase como una alternativa a la anterior. Por su parte, RewriteRule admite otros modificadores propios, como [F] para forzar un acceso denegado (forbidden), o [L] para indicar que es la última regla que debe aplicarse (last rule).
Parámetro | Descripción | Uso |
---|---|---|
[NC] | No Case: para indicar que en la directiva no debe distinguirse entre mayúsculas y minúsculas. | RewriteCond |
[F] | Forbidden: para forzar un acceso denegado. 403 Forbidden. | RewriteRule |
[L] | Last rule: para indicar que es la última regla que debe aplicarse. | RewriteRule |
[N] | Next: indica continuación hasta que las directivas sean logradas | |
[G] | Gone: indica al servidor entregar "Gone" (ya no existe) | |
[P] | Proxy: instruye al servidor para manejar los pedidos por mod_proxy | |
[C] | Chain: Instruye al servidor para encadenar la regla actual con la regla previa. | RewriteCond |
[OR] | Or: para indicar que la expresión actual debe interpretase como una alternativa a la anterior. | RewriteCond |
[R=n] | Redirect: indica redirección. Ej: [R=301] | RewriteRule |
[PT] | Pass Through: pasa el URL al Apache para seguir procesando. | RewriteRule |
[NE] | No Escape: instruye al servidor para analizar las salidas sin escapar carácteres. | |
[NS] | No Subrequest: para saltar directivas de sub-pedidos internos. | |
[QSA] | Append Query String: para agregar un query string al final de la expresión (URL). | RewriteRule |
[S=n] | Skip: para saltar las siguientes "n" reglas. | |
[E=variable:valor] | Environmental Variable: para agregar un valor a una variable. | |
[T=MIME-type] | Mime Type: declara mime-type al recurso. |
El analizador de expresiones proporciona una serie de variables de la forma %{HTTP_HOST}. Tenga en cuenta que el valor de una variable puede depender de la fase del procesamiento de la solicitud en la que se evalúa. Por ejemplo, una expresión usada en una directiva <If > se evalúa antes de que se realice la autenticación. Por lo tanto, %{REMOTE_USER} no se establecerá en este caso.
Variable | Descripción |
---|---|
HTTP_ACCEPT | |
HTTP_COOKIE | |
HTTP_FORWARDED | |
HTTP_HOST | Representa la parte del dominio del URL |
HTTP_PROXY_CONNECTION | |
HTTP_REFERER | |
HTTP_USER_AGENT |
Variable | Descripción |
---|---|
AUTH_TYPE | |
CONN_REMOTE_ADDR | |
CONTEXT_PREFIX | |
CONTEXT_DOCUMENT_TOOT | |
IPV6 | on si la conexión usa IPv6 y off de lo contrario. |
PATH_INFO | |
QUERY_STRING | Es la consulta, lo que esta luego de ? Ej: http://sitio.com/index.php?id=3 osea id=3 |
REMOTE_ADDR | La dirección IP del host remoto (consulte el módulo mod_remoteip). |
REMOTE_HOST | El nombre de host del host remoto |
REMOTE_IDENT | El nombre de usuario establecido por mod_ident |
REMOTE_PORT | El puerto del host remoto (2.4.26 y posterior) |
REMOTE_USER | El nombre del usuario autenticado, si lo hay (no disponible durante <If>) |
REQUEST_METHOD | Método HTTP usado: GET o POST |
Variable | Descripción |
---|---|
DOCUMENT_ROOT | |
SCRIPT_GROUP | |
SCRIPT_USER | |
SERVER_ADDR | |
SERVER_ADMIN | El usuario administrador del HOST actual |
SERVER_NAME | Nombre del servidor HOST actual |
SERVER_PORT | Puerto del servidor HOST actual |
SERVER_PROTOCOL | El protocolo usado en la solicitud. |
SERVER_SOFTWARE | Version de servidor |
Variable | Descripción |
---|---|
API_VERSION | Esta es la versión de la API del módulo httpd de Apache (la interfaz interna entre el servidor y el módulo) en la compilación httpd actual, como se define en include / ap_mmn.h. La versión del módulo API corresponde a la versión de Apache httpd en uso (en la versión de lanzamiento de Apache httpd 1.3.14, por ejemplo, es 19990320: 10), pero es de interés principalmente para los autores de módulos. |
CONN_REMOTE_ADDR | Desde 2.4.8: la dirección IP de la conexión (consulte el módulo mod_remoteip). |
HTTPS | Contendrá el texto "on" si la conexión está usando SSL/TLS, o "off" en caso contrario. (Esta variable se puede usar de forma segura independientemente de si se carga mod_ssl). |
IS_SUBREQ | |
REQUEST_FILENAME | La ruta completa del sistema de archivos local al archivo o script que coincide con la solicitud, si esto ya ha sido determinado por el servidor en el momento en que se hace referencia a REQUEST_FILENAME. De lo contrario, como cuando se usa en un contexto de host virtual, el mismo valor que REQUEST_URI. Dependiendo del valor de AcceptPathInfo, es posible que el servidor solo haya usado algunos de los componentes principales de REQUEST_URI para asignar la solicitud a un archivo. |
REQUEST_SCHEME | Contendrá el esquema de la solicitud (generalmente "http" o "https"). Este valor puede ser influenciado con ServerName. |
REQUEST_STATUS | El estado de error HTTP de la solicitud (no disponible durante <If>) |
REQUEST_LOG_ID | La identificación del registro de errores de la solicitud (ver ErrorLogFormat) |
REQUEST_URI | El componente de ruta del URI solicitado, como "/index.html". Esto excluye notablemente la cadena de consulta que está disponible como su propia variable llamada QUERY_STRING. |
THE_REQUEST | La línea de solicitud HTTP completa enviada por el navegador al servidor (por ejemplo, "GET /index.html HTTP / 1.1"). Esto no incluye ningún encabezado adicional enviado por el navegador. Este valor no se ha salvado (decodificado), a diferencia de la mayoría de las otras variables a continuación. |
Variable | Descripción |
---|---|
TIME_YEAR | Año (2020) |
TIME_MON | Mes (1 a 12) |
TIME_DAY | Dia (1 a 31) |
TIME_HOUR | Hora (0 a 23) |
TIME_MIN | Minutos (0 a 59) |
TIME_SEC | Segundos (0 a 59) |
TIME_WDAY | Dia de la semana (0=Domingo) |
TIME | Fecha y hora. (20201231235959) |
If, Else, ElseIf
<If "%{HTTP_HOST} == 'sitio.com'"> Redirect permanent "/" "http://www.sitio.com/" </If>
De todas formas estos scripts son muy difíciles de depurar por lo que te recomiendo una pagina de testeo.
htaccess tester de makewithlove.
Pronto...
#Este es un comentario RewriteEngine on Options +FollowSymLinks RewriteCond %{HTTP_HOST} ^www\.sitio\.com$ [NC] RewriteRule ^(.*)$ http://sitio.com/$1 [R=301,L]
RewriteEngine on Options +FollowSymLinks RewriteCond %{HTTP_HOST} ^sitio\.com$ [NC] RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteEngine On RewriteRule ^(.*)$ http://www.nuevodominio.com/$1 [R=301,L]
Supongamos que queremos transformar sitio.com/wiki/algo, en sitio.com/index.php/algo
RewriteEngine On RewriteCond %{REQUEST_URI} ^/wiki/ [NC] RewriteRule ^wiki/(.+) /index.php/$1 [R=301,L]
Para eliminar desde cirto punto la URL usa un ? al final ver ejemplo.
Para desviar un rango de IP (10.2.x.x) a otro servidor diferente.
RewriteEngine On RewriteCond %{REMOTE_ADDR} ^10\.2\. RewriteRule (.*) http://sitio.com$1
Cuando se impone mas de un RewriteCond todos deben coincidir para que se aplica RewriteRule. En este caso si tiene la palabra piratear en su cadena de consulta (QUERY_STRING) y en la cookie (HTTP_COOKIE) No tiene la palabra goto, no te lleva a ningun lado.
RewriteEngine On RewriteCond %{QUERY_STRING} piratear [NC] RewriteCond %{HTTP_COOKIE} !goto [NC] RewriteRule . - [F]
Si tu navegador se autoidentifica como navegador de mobil lo enviamos a la pagina mobil.htm si no a la normal.php.
RewriteEngine On RewriteCond %{HTTP_USER_AGENT} (iPhone|Blackberry|Android) RewriteRule ^/$ /mobil.htm [L] RewriteRule ^/$ /normal.php [L]
Si se aplica la primera RewriteRule no se aplica la segunda gracias al modificador [L] (Last Rule)
Tambien podrias eliminar la segunda opcion si en lugar de normal.php usas index.php que es por default.
Cuando tenemos un parametro que queremos convertir en una pagina podemos usar esto.
/index.php?id=3 -> http://sitio.com/3.php /index.php?id=37 -> http://sitio.com/37.php /index.php?id=371 -> http://sitio.com/371.php
RewriteEngine on RewriteCond %{QUERY_STRING} ^id=([0-9]+)$ RewriteRule .* http://sitio.com/%1.php? [R=302,L,QSA]
Si una cierta carpeta no tiene index.* muestra el contenido los archivos.
IndexIgnore *
Algunas referencias usadas para elaborar esta seccion fueron: