Parece haber una cantidad decente de mod_rewrite
hilos flotando últimamente con un poco de confusión sobre cómo funcionan ciertos aspectos. Como resultado, he compilado algunas notas sobre la funcionalidad común y quizás algunos matices molestos.
¿Qué otras funciones / problemas comunes te has encontrado usando mod_rewrite
?
apache
.htaccess
mod-rewrite
Owen
fuente
fuente
Respuestas:
Dónde colocar las reglas mod_rewrite
mod_rewrite
las reglas se pueden colocar dentro delhttpd.conf
archivo o dentro del.htaccess
archivo. si tiene acceso ahttpd.conf
, colocar reglas aquí ofrecerá un beneficio de rendimiento (ya que las reglas se procesan una vez, a diferencia de cada vez.htaccess
que se llama al archivo).Registro de solicitudes mod_rewrite
El registro se puede habilitar desde dentro del
httpd.conf
archivo (incluido<Virtual Host>
):Casos de uso común
Para canalizar todas las solicitudes a un solo punto:
Desde Apache 2.2.16 también puede usar
FallbackResource
.Manejo de redireccionamientos 301/302:
Nota : las redirecciones externas son implícitamente redirecciones 302:
Forzar SSL
Banderas comunes:
[R]
o[redirect]
- forzar una redirección (por defecto es una redirección temporal 302)[R=301]
o[redirect=301]
- forzar un redireccionamiento permanente 301[L]
o[last]
- detener el proceso de reescritura (vea la nota a continuación en los errores comunes)[NC]
o[nocase]
- especificar que la coincidencia no debe distinguir entre mayúsculas y minúsculasEl uso de banderas de formato largo suele ser más legible y ayudará a otros que vengan a leer su código más tarde.
Puede separar varios indicadores con una coma:
Errores comunes
Mezcla de
mod_alias
redireccionamientos de estilo conmod_rewrite
Nota : se puede mezclar
mod_alias
conmod_rewrite
, pero implica más trabajo que simplemente tratando las redirecciones básicos que el anterior.El contexto afecta la sintaxis
Dentro de
.htaccess
archivos, una barra inicial no se utiliza en el patrón RewriteRule:[L] no es el último! (algunas veces)
La
[L]
bandera deja de procesar cualquier regla de reescritura adicional para que pase a través del conjunto de reglas . Sin embargo, si la URL se modificó en esa pasada y estás en el.htaccess
contexto o en la<Directory>
sección, entonces tu solicitud modificada se pasará nuevamente a través del motor de análisis de URL. Y en la siguiente pasada, esta vez puede coincidir con una regla diferente. Si no entiende esto, a menudo parece que su[L]
bandera no tuvo ningún efecto.Nuestro registro de reescritura muestra que las reglas se ejecutan dos veces y la URL se actualiza dos veces:
La mejor manera de evitar esto es usar la
[END]
bandera ( ver documentos de Apache ) en lugar de la[L]
bandera, si realmente desea detener todo el procesamiento posterior de las reglas (y las pasadas posteriores). Sin embargo, la[END]
bandera solo está disponible para Apache v2.3.9 + , por lo que si tiene v2.2 o una versión inferior, solo tiene la[L]
bandera.Para versiones anteriores, debe confiar en
RewriteCond
declaraciones para evitar la coincidencia de reglas en pases posteriores del motor de análisis de URL.O debe asegurarse de que su RewriteRule esté en un contexto (es decir
httpd.conf
) que no hará que se vuelva a analizar su solicitud.fuente
[L]
bandera significa que una regla es la última en el procesamiento actual, esto no dejará de reescribirse, porque son redireccionamientos internos, por lo que sedirB
aplicarádirC
en el próximo procesamiento de htaccess. SoloRewriteRule ^(.*)$ index.php?query=$1
habrá un ciclo infinito de redireccionamientos internos (en la práctica, se termina después de 10 iteraciones). -1 porque sugieres que [L] no es el último . No está terminando el proceso de reescritura, pero es el último .RewriteCond %{HTTPS} off
es la forma preferida de verificar una conexión HTTPS (en su ejemplo de forzar el tráfico no SSL a HTTPS)si necesita 'bloquear' redirecciones / reescrituras internas para que no ocurran en el .htaccess, eche un vistazo a la
condición, como se discute aquí .
fuente
.*
la[L]
bandera que leí antes de llegar aquí.200
,!=200
,^.
,^$
. Aparentemente, la variable se establece en200
para una redirección, pero también otras páginas (error y demás) la establecen en algún valor. Ahora que los medios que o bien comprobar siis empty
,is not empty
,is 200
ois not 200
, dependiendo de lo que necesita.El trato con RewriteBase:
Casi siempre es necesario configurar RewriteBase. Si no lo hace, apache adivina que su base es la ruta del disco físico a su directorio. Así que empieza con esto:
fuente
RewriteBase .
, o algo que indique que debe mantener la URL igual, simplemente cambiando lo que ha especificado?RewriteBase
si está utilizando la sustitución de ruta relativa en laRewriteRule
directiva. Es mejor evitar el uso de rutas relativas.RewriteBase
completo, ya que casi todos los desarrolladores malinterpretan lo que hace. Como dijo @ w3d, solo lo necesita si desea guardar caracteres y desea aplicar la misma base a todas sus RewriteRules en un solo archivo. Es probable que su código sea más claro para los demás si lo evita.Otras trampas:
1- A veces es una buena idea desactivar MultiViews
No estoy bien versado en todas las capacidades de MultiViews, pero sé que arruina mis reglas mod_rewrite cuando está activo, porque una de sus propiedades es intentar 'adivinar' una extensión de un archivo que cree que estoy buscando .
Lo explicaré: suponga que tiene 2 archivos php en su directorio web, file1.php y file2.php y agrega estas condiciones y reglas a su .htaccess:
Asume que todas las URL que no coinciden con un archivo o directorio serán capturadas por file1.php. ¡Sorpresa! Esta regla no se cumple para la URL http: // myhost / file2 / somepath . En su lugar, lo llevan dentro de file2.php.
Lo que está sucediendo es que MultiViews adivinó automáticamente que la URL que realmente deseaba era http: //myhost/file2.php/somepath y con mucho gusto lo llevó allí.
Ahora, no tienes ni idea de lo que acaba de pasar y estás en ese punto cuestionando todo lo que creías saber sobre mod_rewrite. Luego comienzas a jugar con las reglas para tratar de entender la lógica detrás de esta nueva situación, pero cuanto más pruebas, menos sentido tiene.
Bien, en resumen, si desea que mod_rewrite funcione de una manera que se aproxime a la lógica, apagar MultiViews es un paso en la dirección correcta.
2- habilitar FollowSymlinks
Ese, realmente no conozco los detalles, pero lo he visto mencionado muchas veces, así que hazlo.
fuente
+FollowSymLinks
se menciona en la documentación como obligatorio paramod_rewrite
que funcione, por vagas razones de seguridad.La ecuación se puede hacer con el siguiente ejemplo:
Equilibrio de carga dinámico:
Si usa mod_proxy para equilibrar su sistema, es posible agregar un rango dinámico de servidor trabajador.
fuente
Es necesario comprender mejor la bandera [L]. El indicador [L] es el último, solo tiene que entender qué hará que su solicitud sea enrutada nuevamente a través del motor de análisis de URL. De los documentos ( http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_l ) (el énfasis es mío):
Por lo que el indicador [L] hace parada el tratamiento de sus reglas de reescritura más para que pase a través del conjunto de reglas. Sin embargo, si su regla marcada con [L] modificó la solicitud y está en el contexto .htaccess o
<Directory>
sección, entonces su solicitud modificada se pasará nuevamente a través del motor de análisis de URL. Y en la siguiente pasada, esta vez puede coincidir con una regla diferente. Si no comprende lo que sucedió, parece que su primera regla de reescritura con la bandera [L] no tuvo ningún efecto.La mejor manera de evitar esto es usar la bandera [END] ( http://httpd.apache.org/docs/current/rewrite/flags.html#flag_end ) en lugar de la bandera [L], si realmente quieres detener todo el procesamiento posterior de las reglas (y el análisis posterior). Sin embargo, el indicador [FIN] solo está disponible para Apache v2.3.9 +, por lo que si tiene v2.2 o inferior, se quedará con el indicador [L]. En este caso, debe confiar en las declaraciones de RewriteCond para evitar que las reglas coincidan en las pasadas posteriores del motor de análisis de URL. O debe asegurarse de que sus RewriteRule estén en un contexto (es decir, httpd.conf) que no provocará que se vuelva a analizar su solicitud.
fuente
Otra gran característica son las expansiones de reescritura de mapas. Son especialmente útiles si tiene una gran cantidad de hosts / reescrituras para manejar:
Son como un reemplazo de valor clave:
Entonces puedes usar un mapeo en tus reglas como:
Puede encontrar más información sobre este tema aquí:
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#mapfunc
fuente
.htaccess
reescrituras basadas en. No funciona en este contexto.mod_rewrite puede modificar aspectos del manejo de solicitudes sin alterar la URL, por ejemplo, configurar variables de entorno, configurar cookies, etc. Esto es increíblemente útil.
Establezca condicionalmente una variable de entorno:
Devolver una respuesta 503:
RewriteRule
el[R]
indicador 'puede tomar un valor que no sea 3xx y devolver una respuesta que no redireccione, por ejemplo, para el tiempo de inactividad administrado / mantenimiento:devolverá una respuesta 503 (no una redirección per se).
Además, mod_rewrite puede actuar como una interfaz superpoderosa para mod_proxy, por lo que puede hacer esto en lugar de escribir
ProxyPass
directivas:Opinión: Usando
RewriteRule
syRewriteCond
para enrutar solicitudes a diferentes aplicaciones o balanceadores de carga en función de prácticamente cualquier aspecto concebible de la solicitud es inmensamente poderoso. Controlar las solicitudes en su camino hacia el backend y poder modificar las respuestas en su camino de regreso hace que mod_rewrite sea el lugar ideal para centralizar todas las configuraciones relacionadas con el enrutamiento.Tómate el tiempo para aprenderlo, ¡vale la pena! :)
fuente