orden de sintaxis mod_rewrite
mod_rewrite tiene algunas reglas de orden específicas que afectan el procesamiento. Antes de que se haga algo, la RewriteEngine On
directiva debe ser dada ya que esto activa el procesamiento mod_rewrite. Esto debería ser antes de cualquier otra directiva de reescritura.
RewriteCond
el precedente RewriteRule
hace que UNA regla esté sujeta al condicional. Las siguientes RewriteRules se procesarán como si no estuvieran sujetas a condicionales.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
En este caso simple, si el referente HTTP es de serverfault.com, redirija las solicitudes de blog a páginas especiales de servidor por defecto (somos así de especiales). Sin embargo, si el bloque anterior tenía una línea RewriteRule adicional:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg $/blog/$1.sf.jpg
Todos los archivos .jpg irían a las páginas especiales de servidor por defecto, no solo los que tienen un referente que indica que proviene de aquí. Claramente, esta no es la intención de cómo se escriben estas reglas. Se podría hacer con múltiples reglas RewriteCond:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
Pero probablemente debería hacerse con una sintaxis de reemplazo más complicada.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
El RewriteRule más complejo contiene los condicionales para el procesamiento. El último paréntesis, (html|jpg)
le dice a RewriteRule que coincida con uno html
o jpg
, y que represente la cadena coincidente como $ 2 en la cadena reescrita. Esto es lógicamente idéntico al bloque anterior, con dos pares RewriteCond / RewriteRule, solo lo hace en dos líneas en lugar de cuatro.
Múltiples líneas RewriteCond están AND implícitamente y pueden OR explícitamente. Para manejar referencias de ServerFault y Super User (OR explícito):
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [OR]
RewriteCond %{HTTP_REFERER} ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
Para servir páginas referidas por ServerFault con navegadores Chrome (Y implícito):
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
RewriteBase
también es específico de la orden, ya que especifica cómo las siguientes RewriteRule
directivas manejan su procesamiento. Es muy útil en archivos .htaccess. Si se usa, debería ser la primera directiva bajo "RewriteEngine on" en un archivo .htaccess. Toma este ejemplo:
RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
Esto le dice a mod_rewrite que esta URL particular que está manejando actualmente llegó a través de http://example.com/blog/ en lugar de la ruta del directorio físico (/ home / $ Username / public_html / blog) y para tratarla en consecuencia. Debido a esto, RewriteRule
considera que el inicio de cadena es posterior al "/ blog" en la URL. Aquí está lo mismo escrito de dos maneras diferentes. Uno con RewriteBase, el otro sin:
RewriteEngine On
##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg) $1.sf.$2
##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
Como puede ver, RewriteBase
permite que las reglas de reescritura aprovechen la ruta del sitio web al contenido en lugar del servidor web , lo que puede hacerlas más inteligibles para quienes editan dichos archivos. Además, pueden acortar las directivas, lo que tiene un atractivo estético.
Sintaxis de coincidencia RewriteRule
RewriteRule tiene una sintaxis compleja para hacer coincidir cadenas. Cubriré las banderas (cosas como [PT]) en otra sección. Como los administradores de sistemas aprenden con el ejemplo con más frecuencia que leyendo una página de manual , daré ejemplos y explicaré lo que hacen.
RewriteRule ^/blog/(.*)$ /newblog/$1
La .*
construcción coincide con cualquier carácter individual ( .
) cero o más veces ( *
). Encerrándolo entre paréntesis le dice que proporcione la cadena que coincidió con la variable $ 1.
RewriteRule ^/blog/.*/(.*)$ /newblog/$1
En este caso, el primer. * NO estaba encerrado en parens, por lo que no se proporciona a la cadena reescrita. Esta regla elimina un nivel de directorio en el nuevo blog-sitio. (/blog/2009/sample.html se convierte en /newblog/sample.html).
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$2
En este caso, la primera expresión de paréntesis establece un grupo coincidente. Esto se convierte en $ 1, que no es necesario y, por lo tanto, no se usa en la cadena reescrita.
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$1/$2
En este caso, usamos $ 1 en la cadena reescrita.
RewriteRule ^/blog/(20[0-9][0-9])/(.*)$ /newblog/$1/$2
Esta regla utiliza una sintaxis de paréntesis especial que especifica un rango de caracteres . [0-9] coincide con los números del 0 al 9. Esta regla específica manejará años del 2000 al 2099.
RewriteRule ^/blog/(20[0-9]{2})/(.*)$ /newblog/$1/$2
Esto hace lo mismo que la regla anterior, pero la parte {2} le dice que coincida con el carácter anterior (una expresión de paréntesis en este caso) dos veces.
RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html /newblog/$1/$2.shtml
Este caso coincidirá con cualquier letra minúscula en la segunda expresión coincidente, y lo hará para tantos caracteres como sea posible. La \.
construcción le dice que trate el período como un período real, no el carácter especial que es en los ejemplos anteriores. Sin embargo, se romperá si el nombre de archivo tiene guiones.
RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html /newblog/$1/$2.shtml
Esto atrapa nombres de archivo con guiones en ellos. Sin embargo, como -
es un carácter especial en las expresiones de paréntesis, tiene que ser el primer carácter de la expresión.
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
Esta versión atrapa cualquier nombre de archivo con letras, números o el -
carácter en el nombre del archivo. Así es como especifica varios conjuntos de caracteres en una expresión de paréntesis.
RewriteRule flags
Las banderas en las reglas de reescritura tienen una gran cantidad de significados y casos de uso especiales .
RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html /newblog/$1/$2.shtml [L]
La bandera está [L]
al final de la expresión anterior. Se pueden usar varias banderas, separadas por una coma. La documentación vinculada describe cada uno, pero aquí están de todos modos:
L = último. Deje de procesar RewriteRules una vez que este coincida. ¡El orden cuenta!
C = Cadena. Continúe procesando la próxima RewriteRule. Si esta regla no coincide, la siguiente regla no se ejecutará. Más sobre esto más tarde.
E = Establecer variable ambiental. Apache tiene varias variables ambientales que pueden afectar el comportamiento del servidor web.
F = prohibido. Devuelve un error 403 prohibido si esta regla coincide.
G = ido. Devuelve un error 410-Gone si esta regla coincide.
H = controlador. Obliga a que la solicitud se maneje como si fuera el tipo MIME especificado.
N = Siguiente Obliga a la regla a comenzar de nuevo y volver a coincidir. ¡TEN CUIDADO! Se pueden producir bucles.
NC = Sin caso. Permitejpg
para que coincida con jpg y JPG.
NE = Sin escape. Impide la reescritura de caracteres especiales (.? # Y etc.) en sus equivalentes de código hexadecimal.
NS = Sin subrequests. Si está utilizando el servidor incluye, esto evitará coincidencias con los archivos incluidos.
P = Proxy. Obliga a la regla a ser manejada por mod_proxy. Proporcione contenido de otros servidores de forma transparente, ya que su servidor web lo recupera y lo vuelve a servir. Este es un indicador peligroso, ya que uno mal escrito convertirá su servidor web en un proxy abierto y eso es malo.
PT = Paso a través. Tenga en cuenta las declaraciones de alias en la coincidencia de RewriteRule.
QSA = QSAppend. Cuando la cadena original contiene una consulta ( http://example.com/thing?asp=foo) agrega la cadena de consulta original a la cadena reescrita. Normalmente se descartaría. Importante para contenido dinámico.
R = Redirigir. Proporcione una redirección HTTP a la URL especificada. También puede proporcionar el código de redireccionamiento exacto [R = 303]. Muy similar a RedirectMatch
, que es más rápido y debe usarse cuando sea posible.
S = Saltar. Salta esta regla.
T = Tipo. Especifique el tipo mime del contenido devuelto. Muy similar a la AddType
directiva.
¿Sabes cómo dije que eso se RewriteCond
aplica a una sola regla? Bueno, puedes evitar eso encadenando.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html [C]
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
Debido a que la primera RewriteRule tiene el indicador de cadena, la segunda regla de reescritura se ejecutará cuando la primera lo haga, que es cuando la regla anterior RewriteCond coincide. Útil si las expresiones regulares de Apache le duelen el cerebro. Sin embargo, el método todo en una línea que señalo en la primera sección es más rápido desde el punto de vista de la optimización.
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
Esto se puede simplificar mediante banderas:
RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html /newblog/$1/$2.shtml [NC]
Además, algunas banderas también se aplican a RewriteCond. En particular, NoCase.
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [NC]
Coincidirá con "ServerFault.com"