RewriteBase
viene applicato solo al target di una regola di riscrittura relativa .
Utilizzando RewriteBase in questo modo ...
RewriteBase /folder/
RewriteRule a\.html b.html
è essenzialmente lo stesso di ...
RewriteRule a\.html /folder/b.html
Ma quando il file .htaccess è dentro, /folder/
anche questo punta allo stesso target:
RewriteRule a\.html b.html
Sebbene i documenti implichino sempre l'utilizzo di a RewriteBase
, Apache di solito lo rileva correttamente per i percorsi in DocumentRoot a meno che:
In questi casi, potrebbe essere necessario specificare RewriteBase.
Tuttavia, poiché si tratta di una direttiva confusa, in genere è meglio semplicemente specificare URI assoluti (ovvero "relativi alla radice") nei target di riscrittura. Altri sviluppatori che leggono le tue regole li afferreranno più facilmente.
Citando qui l'eccellente risposta approfondita di Jon Lin :
In un file htaccess, mod_rewrite funziona in modo simile a a <Directory>
o <Location>
container. e il RewriteBase
è usato per fornire una base di percorso relativa.
Ad esempio, supponiamo di avere questa struttura di cartelle:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
Quindi puoi accedere a:
http://example.com/
(radice)
http://example.com/subdir1
(Subdir1)
http://example.com/subdir2
(Subdir2)
http://example.com/subdir2/subsubdir
(Subsubdir)
L'URI che viene inviato tramite a RewriteRule
è relativo alla directory contenente il file htaccess. Quindi se hai:
RewriteRule ^(.*)$ -
- Nel root htaccess, e la richiesta è
/a/b/c/d
, quindi l'URI acquisito ( $1
) è a/b/c/d
.
- Se la regola è attiva
subdir2
e la richiesta è /subdir2/e/f/g
quindi l'URI acquisito è e/f/g
.
- Se la regola è in
subsubdir
e la richiesta lo è /subdir2/subsubdir/x/y/z
, l'URI acquisito lo è x/y/z
.
La directory in cui si trova la regola ha quella parte rimossa dall'URI. La base di riscrittura non ha alcun effetto su questo, questo è semplicemente come funziona per directory.
Che la base riscrittura fa fare, è fornire una base di URL-path ( non una base file-path) per tutti i percorsi relativi nella destinazione della regola . Quindi dire che hai questa regola:
RewriteRule ^foo$ bar.php [L]
La bar.php
è un percorso relativo, al contrario di:
RewriteRule ^foo$ /bar.php [L]
dove il /bar.php
è un percorso assoluto. Il percorso assoluto sarà sempre il "root" (nella struttura di directory sopra). Ciò significa che indipendentemente dal fatto che la regola sia in "root", "subdir1", "subsubdir", ecc., Il /bar.php
percorso viene sempre mappato http://example.com/bar.php
.
Ma l'altra regola, con il relativo percorso, si basa sulla directory in cui si trova la regola. Quindi se
RewriteRule ^foo$ bar.php [L]
è nella "radice" e vai a http://example.com/foo
, vieni servito http://example.com/bar.php
. Ma se quella regola si trova nella directory "subdir1" e vai a http://example.com/subdir1/foo
, vieni servito http://example.com/subdir1/bar.php
. ecc. A volte questo funziona e talvolta no, come dice la documentazione, dovrebbe essere richiesto per percorsi relativi, ma il più delle volte sembra funzionare. Tranne quando stai reindirizzando (usando la R
bandiera, o implicitamente perché hai http://host
nel bersaglio della tua regola). Ciò significa che questa regola:
RewriteRule ^foo$ bar.php [L,R]
se è nella directory "subdir2", e si va a http://example.com/subdir2/foo
, mod_rewrite sarà confondere il percorso relativo come file-percorso invece di un URL-path e per la R
bandiera, si finirà per ottenere reindirizzato a qualcosa come: http://example.com/var/www/localhost/htdocs/subdir1
. Che ovviamente non è quello che vuoi.
È qui che RewriteBase
entra in gioco. La direttiva dice a mod_rewrite cosa aggiungere all'inizio di ogni percorso relativo. Quindi se ho:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
in "subsubdir", http://example.com/subdir2/subsubdir/foo
effettivamente mi servirà http://example.com/blah/bar.php
. Il "bar.php" viene aggiunto alla fine della base. In pratica, questo esempio di solito non è quello che vuoi, perché non puoi avere più basi nello stesso contenitore di directory o file htaccess.
Nella maggior parte dei casi, viene utilizzato in questo modo:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
dove quelle regole sarebbero nella directory "subdir1" e
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
sarebbe nella directory "subsubdir".
Questo in parte ti consente di rendere portatili le tue regole, in modo da poterle rilasciare in qualsiasi directory e devi solo cambiare la base invece di un mucchio di regole. Ad esempio se avessi:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
tale che http://example.com/subdir1/foo
servirà http://example.com/subdir1/bar.php
ecc. E dire che hai deciso di spostare tutti quei file e regole nella directory "subsubdir". Invece di cambiare ogni istanza di /subdir1/
a/subdir2/subsubdir/
, avresti potuto avere una base:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
E poi quando hai bisogno di spostare quei file e le regole in un'altra directory, basta cambiare la base:
RewriteBase /subdir2/subsubdir/
e basta.