RewriteBase
solo se aplica al objetivo de una regla de reescritura relativa .
Usando RewriteBase como este ...
RewriteBase /folder/
RewriteRule a\.html b.html
es esencialmente lo mismo que ...
RewriteRule a\.html /folder/b.html
Pero cuando el archivo .htaccess está dentro /folder/
, esto también apunta al mismo objetivo:
RewriteRule a\.html b.html
Aunque los documentos implican siempre usar un RewriteBase
, Apache generalmente lo detecta correctamente para las rutas bajo DocumentRoot a menos que:
En estos casos, puede encontrar que necesita especificar RewriteBase.
Sin embargo, dado que es una directiva confusa, generalmente es mejor simplemente especificar URI absolutos (también conocidos como 'raíz relativa') en sus objetivos de reescritura. Otros desarrolladores que lean sus reglas las comprenderán más fácilmente.
Citando la excelente respuesta en profundidad de Jon Lin aquí :
En un archivo .htaccess, mod_rewrite funciona de forma similar a una <Directory>
o <Location>
contenedor. y RewriteBase
se usa para proporcionar una base de ruta relativa.
Por ejemplo, supongamos que tiene esta estructura de carpetas:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
Para que pueda acceder a:
http://example.com/
(raíz)
http://example.com/subdir1
(subdir1)
http://example.com/subdir2
(subdir2)
http://example.com/subdir2/subsubdir
(subsubdir)
El URI que se envía a través de un RewriteRule
es relativo al directorio que contiene el archivo htaccess. Entonces si tienes:
RewriteRule ^(.*)$ -
- En la raíz htaccess, y la solicitud es
/a/b/c/d
, entonces el URI capturado ( $1
) es a/b/c/d
.
- Si la regla está dentro
subdir2
y la solicitud es /subdir2/e/f/g
entonces, el URI capturado es e/f/g
.
- Si la regla está en
subsubdir
, y la solicitud está /subdir2/subsubdir/x/y/z
, entonces el URI capturado está x/y/z
.
El directorio en el que se encuentra la regla tiene esa parte eliminada del URI. La base de reescritura no tiene ningún efecto en esto, así es simplemente cómo funciona por directorio.
Lo que la base de reescritura no lo hacen, es proporcionar una base URL-path ( no una base file-path) de las rutas relativas en el objetivo de la regla . Digamos que tienes esta regla:
RewriteRule ^foo$ bar.php [L]
El bar.php
es un camino relativo, en oposición a:
RewriteRule ^foo$ /bar.php [L]
donde el /bar.php
es un camino absoluto. La ruta absoluta siempre será la "raíz" (en la estructura de directorios anterior). Eso significa que independientemente de si la regla está en la "raíz", "subdir1", "subsubdir", etc., la /bar.php
ruta siempre se asigna http://example.com/bar.php
.
Pero la otra regla, con la ruta relativa, se basa en el directorio en el que se encuentra la regla. Entonces, si
RewriteRule ^foo$ bar.php [L]
está en la "raíz" y vas a http://example.com/foo
, te sirven http://example.com/bar.php
. Pero si esa regla está en el directorio "subdir1", y usted va http://example.com/subdir1/foo
, se le servirá http://example.com/subdir1/bar.php
. etc. Esto a veces funciona y a veces no, como dice la documentación, se supone que es necesario para rutas relativas, pero la mayoría de las veces parece funcionar. Excepto cuando está redirigiendo (usando la R
bandera, o implícitamente porque tiene http://host
en el objetivo de su regla). Eso significa esta regla:
RewriteRule ^foo$ bar.php [L,R]
si está en el directorio "subdir2", y te vas a http://example.com/subdir2/foo
, mod_rewrite confundirá la ruta relativa como un archivo de ruta en lugar de una dirección URL de la ruta y debido a la R
bandera, que va a terminar siendo redirigido a algo como: http://example.com/var/www/localhost/htdocs/subdir1
. Lo cual obviamente no es lo que quieres.
Aquí es donde RewriteBase
entra. La directiva le dice a mod_rewrite qué agregar al comienzo de cada ruta relativa. Entonces si tengo:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
en "subsubdir", ir a http://example.com/subdir2/subsubdir/foo
realmente me servirá http://example.com/blah/bar.php
. El "bar.php" se agrega al final de la base. En la práctica, este ejemplo generalmente no es lo que desea, porque no puede tener múltiples bases en el mismo contenedor de directorio o archivo htaccess.
En la mayoría de los casos, se usa así:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
donde esas reglas estarían en el directorio "subdir1" y
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
estaría en el directorio "subsubdir".
Esto en parte le permite hacer que sus reglas sean portátiles, por lo que puede colocarlas en cualquier directorio y solo necesita cambiar la base en lugar de un montón de reglas. Por ejemplo si tuvieras:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
tal que va a http://example.com/subdir1/foo
servir, http://example.com/subdir1/bar.php
etc. Y digamos que decidió mover todos esos archivos y reglas al directorio "subsubdir". En lugar de cambiar cada instancia de /subdir1/
a /subdir2/subsubdir/
, podría haber tenido una base:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
Y luego, cuando necesita mover esos archivos y las reglas a otro directorio, simplemente cambie la base:
RewriteBase /subdir2/subsubdir/
y eso es.