Perché ottengo una doppia barra finale a seconda di dove si trova la mia RewriteRule?


9

Sto usando il seguente codice per indirizzare tutte le richieste www a URL non www:

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

Funziona benissimo all'interno di un file .htaccess nella radice del mio sito web.
Ad esempio,
www.example.com -> example.com/
www.example.com/ -> example.com/
www.example.com/other_page -> example.com/other_page

Tuttavia, se sposto questo stesso codice nella mia configurazione VirtualHost, gli URL riscritti contengono una doppia barra finale.
www.example.com -> example.com//
www.example.com/ -> example.com//
www.example.com/other_page -> example.com//other_page

L'ho risolto rimuovendo la barra dalla regola di riscrittura:

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

Ma non riesco a capire il motivo di ciò. Qualcuno sa perché?

Risposte:


10

A quanto ho capito, nei file .htaccess, la stringa che mod_rewrite elabora nella tua regola è relativa alla directory in cui si trova il file .htaccess, quindi non avrà un / all'inizio.

Nella voce VirtualHost, la stringa che elabora è assoluta alla radice del server e quindi include /.

Fa differenze sottili nel modo in cui funziona mod_rewrite.

Ecco qualcuno con un problema simile e soluzione:

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

Questo dovrebbe funzionare in entrambi i casi, supponendo che mi ricordi la mia fuga corretta:

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

Grazie! Adesso capisco perché, almeno. Tuttavia, è meglio per qualche motivo che rimuovere semplicemente / prima del $ 1 come mostro nella mia domanda originale?
Davekaro,

1
Non meglio o peggio, è solo un blocco che puoi scambiare tra .htaccess di VirtualHost senza doverlo modificare ogni volta per gestire le differenze di contesto. Se la tua strada funziona per te, mantienila! :)
Neobyte,

Oh giusto, il tuo metodo funzionerà sia in .htaccess che in VirtualHost. Questo lo rende migliore IMO :)
davekaro l'

4
Ho avuto lo stesso identico problema di @davekaro e ho provato la tua soluzione. L'ultima riga non ha funzionato per me. RewriteRule ^/?(.*)$ http://example.com/$1 [R=301,L]ha fatto il trucco.
Kenny Rasschaert,

2

Sta succedendo perché stai catturando una barra iniziale (.*)e quindi applicandone un'altra prima nella nuova posizione /$1. Non era successo prima perché mod_rewrite si comporta in modo leggermente diverso quando si opera in un contesto per directory rispetto a un contesto per server.

Puoi evitarlo prevenendo facoltativamente la barra. Inoltre puoi usare RedirectMatch in un VirtualHost vuoto con i tuoi domini in eccesso, il che crea un po 'meno elaborazione e può apparire più pulito.

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


Bello. Mi piace l'approccio RedirectMatch. Probabilmente ci andrò con questo dal momento che è davvero un reindirizzamento che voglio realizzare.
Davekaro,

1

Sto includendo questo post per completezza.

La documentazione di Apache spiega perché questo comportamento si verifica molto bene ed è la ragione per cui esiste la direttiva "RewriteBase".

Includere semplicemente la direttiva "RewriteBase" nel file .htaccess per ottenere il risultato desiderato.

Esempio:

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

Dalla documentazione mod_rewrite di Apache 2.2:

La direttiva RewriteBase imposta esplicitamente l'URL di base per le riscritture per directory.

La mia regola empirica è usare quasi sempre "RewriteBase" nei file .htaccess e non usarlo nella configurazione di Apache.


0

Non ho avuto il tempo di gestire questo problema, quindi basta riscrivere // in / :)

RewriteCond %{THE_REQUEST} //
RewriteRule ^(.*)$ http://domain.com [R=301,L]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.