¿Qué hace RewriteBase y cómo usarlo?

Estoy tratando de aprender algunos trucos de .htaccess . Encontré la directiva RewriteBase pero no pude hacerlo funcionar correctamente.

Me pregunto qué hace esta directiva específicamente y cómo usarla. Hubo algunas discusiones sobre RewriteBase en StackOverflow y la documentación de Apache, pero aun así, no pude obtener una respuesta clara a mi pregunta.

¿Podría alguien mostrarme un ejemplo simple pero efectivo donde se puede usar RewriteBase ?

En un archivo htaccess, mod_rewrite funciona de forma similar a un contenedor o . y RewriteBase se usa para proporcionar una base de ruta relativa.

Por ejemplo, supongamos que tienes esta estructura de carpetas:

 root |-- subdir1 |-- subdir2 |-- subsubdir 

Para que pueda acceder:

  • http://example.com/ (root)
  • 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 RewriteRule es relativo al directorio. Entonces si tienes:

 RewriteRule ^(.*)$ - 

en la raíz, y la solicitud es /a/b/c/d , entonces el URI capturado ( $1 ) es a/b/c/d . Pero si la regla está en subdir2 y la solicitud es /subdir2/e/f/g entonces el URI capturado es e/f/g . Y si la regla está en el subsubdir , y la solicitud es /subdir2/subsubdir/x/y/z , entonces el URI capturado es x/y/z . El directorio en el que se encuentra la regla tiene esa parte desmantelada del URI. La base de reescritura no tiene ningún efecto sobre esto, esto es simplemente cómo funciona por directorio.

Lo que hace la base de reescritura es proporcionar una base de ruta de URL ( no una base de ruta de archivo) para ninguna ruta relativa en el objective de la regla. Entonces di que tienes esta regla:

 RewriteRule ^foo$ bar.php [L] 

El bar.php es una ruta relativa, a diferencia de:

 RewriteRule ^foo$ /bar.php [L] 

donde /bar.php es una ruta absoluta. La ruta absoluta siempre será la “raíz” (en la estructura de directorios anterior). Eso significa que si la regla está en la “raíz”, “subdir1”, “subsubdir”, etc. La ruta /bar.php siempre se asigna a http://example.com/bar.php .

Pero la otra regla, con la ruta relativa, se basa en el directorio en el que está 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 va a http://example.com/subdir1/foo , se le servirá http://example.com/subdir1/bar.php . Esto a veces funciona y otras veces no, como dice la documentación, se supone que es necesario para trayectos relativos, pero la mayoría de las veces parece funcionar. Excepto cuando está redirigiendo (usando el indicador R , o implícitamente porque tiene http://host en el objective de su regla). Eso significa esta regla:

 RewriteRule ^foo$ bar.php [L,R] 

si está en el directorio “subdir2”, y vas a http://example.com/subdir2/foo , mod_rewrite confundirá la ruta relativa como una ruta de archivo en lugar de una ruta URL y debido a la bandera R , Se redirigirá a algo como: http://example.com/var/www/localhost/htdocs/subdir1 . Lo cual obviamente no es lo que quieres.

Aquí es donde entra RewriteBase . 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] 

y esa regla está en “subsubdir”, ir a http://example.com/subdir2/subsubdir/foo me servirá realmente 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 varias 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, para que pueda colocarlas en cualquier directorio y solo necesite cambiar la base en lugar de un conjunto 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] ... 

de modo que yendo 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 necesitó mover esos archivos y las reglas a otro directorio, simplemente cambie la base:

 RewriteBase /subdir2/subsubdir/ 

y eso es.

La respuesta de 1 línea es: Rewritebase establece la ruta base de la reescritura arg2 .

Eso es literalmente eso. (por lo que funciona como html basehref, ⨕ excepto que es útil ya que a menudo en el contexto de la reescritura de URL no se desea la base predeterminada [ . ]).

Rewritebase facilita el mantenimiento si tiene varias reescrituras. De hecho, si solo está utilizando una línea de reescritura, entonces rewritebase es bastante inútil (ya que simplemente puede reescribir la url basada).


Nota al margen

Por supuesto, puede ignorar por completo la base de escritura de reescritura, utilizando solo rutas absolutas para las regrabaciones.


Relacionado

  • una base de reescritura sin uso [coincidental]