¿Por qué obtengo una barra diagonal doble dependiendo de dónde se encuentre mi RewriteRule?

9

Estoy usando el siguiente código para dirigir todas las solicitudes de www a URL que no sean www:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

Esto funciona muy bien dentro de un archivo .htaccess en la raíz de mi sitio web.
Por ejemplo,
www.example.com -> example.com/
www.example.com/ -> example.com/
www.example.com/other_page -> example.com/other_page

Sin embargo, si muevo este mismo código a mi configuración de VirtualHost, las URL reescritas contienen una barra diagonal doble.
www.example.com -> example.com//
www.example.com/ -> example.com//
www.example.com/other_page -> example.com//other_page

Lo arreglé eliminando la barra diagonal de la regla de reescritura:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com$1 [R=301,L]

Pero no puedo entender la razón de esto. Alguien sabe por qué?

davekaro
fuente

Respuestas:

10

Según tengo entendido, en los archivos .htaccess, la cadena que mod_rewrite procesa en su regla es relativa al directorio en el que se encuentra el archivo .htaccess, por lo que no tendrá un / al inicio.

En la entrada VirtualHost, la cadena que procesa es absoluta para la raíz del servidor y, por lo tanto, incluye el /.

Hace diferencias sutiles en cómo funciona mod_rewrite.

Aquí hay alguien con un problema similar y una solución:

http://forum.modrewrite.com/viewtopic.php?p=56322&sid=77f72967f59200b5b5de174440234c3a

Esto debería funcionar en ambos casos, suponiendo que recuerdo que escapé correctamente:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^\/?(.*?)$ http://example.com/$1 [R=301,L]
Neobyte
fuente
¡Gracias! Ahora entiendo por qué, al menos. Sin embargo, ¿es esto mejor por alguna razón que simplemente eliminar / antes de los $ 1 como muestro en mi pregunta original?
davekaro
1
No es mejor ni peor, es solo un bloque que puede intercambiar entre .htaccess de VirtualHost sin tener que editarlo cada vez para manejar las diferencias de contexto. Si su camino funciona para usted, ¡quédese con él! :)
Neobyte
Ah, sí, su método funcionará tanto en .htaccess como en VirtualHost. Eso lo hace mejor OMI :)
davekaro
44
Tuve exactamente el mismo problema que @davekaro y probé tu solución. La última línea no funcionó para mí. RewriteRule ^/?(.*)$ http://example.com/$1 [R=301,L]Hizo el truco.
Kenny Rasschaert
2

Está sucediendo porque está capturando una barra diagonal inicial (.*)y luego aplica otra barra diagonal antes en la nueva ubicación /$1. No sucedió antes porque mod_rewrite se comporta de manera ligeramente diferente cuando se opera en un contexto por directorio en lugar de un contexto por servidor.

Podrías evitar esto, opcionalmente, eliminando la barra diagonal. Además, puede usar RedirectMatch en un VirtualHost vacío con sus dominios excedentes, lo que crea un poco menos de procesamiento y puede verse más limpio.

<VirtualHost *>
ServerName example.com
ServerAlias other.example.com
..
RedirectMatch permanent ^/?(.*) http://example.com/$1
</VirtualHost>

Dan Carley
fuente
Agradable. Me gusta el enfoque RedirectMatch. Probablemente seguiré con esto, ya que realmente es una redirección que quiero lograr.
davekaro
1

Estoy incluyendo esta publicación para completar.

La documentación de Apache explica por qué este comportamiento ocurre muy bien y es la razón por la que existe la directiva 'RewriteBase'.

Simplemente incluir la directiva 'RewriteBase' en su archivo .htaccess debería lograr el resultado deseado.

Ejemplo:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

De la documentación de Apache 2.2 mod_rewrite:

La directiva RewriteBase establece explícitamente la URL base para reescrituras por directorio.

Mi regla general es usar casi siempre 'RewriteBase' en archivos .htaccess, y no usarlo en la configuración de Apache.


fuente
0

No tuve tiempo para manejar este problema, así que solo vuelva a escribir // en / :)

RewriteCond %{THE_REQUEST} //
RewriteRule ^(.*)$ http://domain.com [R=301,L]
usuario956584
fuente