Por que obtenho uma barra dupla à direita dependendo de onde o meu RewriteRule está localizado?

8

Estou usando o código a seguir para direcionar todas as solicitações de www para URLs sem www:

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

Isso funciona muito bem dentro de um arquivo .htaccess na raiz do meu site.
Por exemplo,
www.example.com - > example.com/
www.example.com/ - > example.com/
www.example.com/other_page - > example.com/other_page

No entanto, se eu mover esse mesmo código para minha configuração do VirtualHost, as URLs reescritas conterão uma barra dupla no final.
www.example.com - > example.com//
www.example.com/ - > example.com//
www.example.com/other_page - > example.com//other_page

Eu consertei removendo a barra da regra de reescrita:

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

Mas não consigo entender o motivo disso. Alguém sabe por quê?

    
por davekaro 11.06.2009 / 16:46

4 respostas

8

Pelo que entendi, nos arquivos .htaccess, a string que o mod_rewrite processa na sua regra é relativa ao diretório no qual o arquivo .htaccess está, então ele não terá um / no início.

Na entrada VirtualHost, a string que ela processa é absoluta para a raiz do servidor e, portanto, inclui o arquivo /.

Isso cria diferenças sutis em como o mod_rewrite funciona.

Aqui está alguém com um problema e uma solução semelhantes:

link

Isso deve funcionar nos dois casos, supondo que eu me lembre de ter escapado corretamente:

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

Isso está acontecendo porque você está capturando uma barra inicial com (.*) e, em seguida, aplicando outra barra antes no novo local /$1 . Isso não aconteceu antes, porque o mod_rewrite se comporta de maneira um pouco diferente quando operando em um contexto por diretório em oposição a um contexto por servidor.

Você pode evitar isso opcionalmente antecipando a barra. Além disso, você pode usar o RedirectMatch em um VirtualHost vazio com seus domínios excedentes, o que cria um processamento um pouco menor e pode parecer mais limpo.

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

    
por 11.06.2009 / 17:03
1

Estou incluindo este post para ser completo.

A documentação do Apache explica por que esse comportamento ocorre muito bem e é a razão pela qual a diretiva "RewriteBase" existe.

Simplesmente incluir a diretiva "RewriteBase" em seu arquivo .htaccess deve atingir o resultado desejado.

Exemplo:

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

Da documentação do mod_rewrite do Apache 2.2:

The RewriteBase directive explicitly sets the base URL for per-directory rewrites.

Minha regra é quase sempre usar 'RewriteBase' em arquivos .htaccess, e não usá-lo na configuração do Apache.

    
por 12.06.2009 / 00:41
0

Não tive tempo de lidar com este problema, por isso reescreva // para /:)

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