Come funziona RewriteBase in .htaccess

Ho visto questo in alcuni esempi .htaccess

 RewriteBase / 

Sembra essere in qualche modo simile nella funzionalità del di HTML.

Credo che possa anteporre automaticamente il suo valore all’inizio delle istruzioni RewriteRule (possibilmente senza una barra principale)?

Non riuscivo a farlo funzionare correttamente. Penso che il suo utilizzo potrebbe rivelarsi molto utile per la portabilità del sito, poiché spesso ho un server di sviluppo diverso da quello di produzione. Il mio metodo attuale mi lascia eliminare alcune parti dalle mie istruzioni RewriteRule .

Qualcuno può spiegarmi brevemente come implementarlo?

Grazie

Nelle mie parole, dopo aver letto i documenti e sperimentato:

È ansible utilizzare RewriteBase per fornire una base per le riscritture. Considera questo

 # invoke rewrite engine RewriteEngine On RewriteBase /~new/ # add trailing slash if missing rewriteRule ^(([a-z0-9\-]+/)*[a-z0-9\-]+)$ $1/ [NC,R=301,L] 

Questa è una regola reale che ho usato per garantire che gli URL abbiano una barra finale. Questo convertirà

 http://www.example.com/~new/page 

a

 http://www.example.com/~new/page/ 

RewriteBase lì il RewriteBase , si rende il percorso relativo fuori dal parametro RewriteBase .

RewriteBase viene applicato solo alla destinazione di una regola di riscrittura relativa .

  • Usando RewriteBase come questo …

     RewriteBase /folder/ RewriteRule a\.html b.html 
  • è essenzialmente lo stesso di …

     RewriteRule a\.html /folder/b.html 
  • Ma quando il file .htaccess è dentro /folder/ allora questo punta anche alla stessa destinazione:

     RewriteRule a\.html b.html 

Sebbene i documenti implichino sempre l’utilizzo di una RewriteBase , in genere Apache lo rileva correttamente per i percorsi sotto DocumentRoot a meno che:

  • Stai usando le direttive di Alias

  • Stai utilizzando le regole di riscrittura .htaccess per eseguire i reindirizzamenti HTTP (anziché solo la riscrittura silenziosa) agli URL relativi

In questi casi, potresti scoprire che devi specificare il RewriteBase.

Tuttavia, poiché si tratta di una direttiva che genera confusione, in genere è meglio specificare semplicemente URI assoluti (noti come “root relative”) nei target di riscrittura. Altri sviluppatori che leggono le tue regole potranno cogliere questi più facilmente.


Citando l’eccellente risposta approfondita di Jon Lin qui :

In un file htaccess, mod_rewrite funziona in modo simile a un contenitore o . e la RewriteBase viene utilizzata 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/ (root)
  • http://example.com/subdir1 (sottodir1)
  • http://example.com/subdir2 (subdir2)
  • http://example.com/subdir2/subsubdir (subsubdir)

L’URI che viene inviato attraverso una 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 catturato ( $1 ) è a/b/c/d .
  • Se la regola è in subdir2 e la richiesta è /subdir2/e/f/g l’URI catturato è e/f/g .
  • Se la regola si trova nel subsubdir e la richiesta è /subdir2/subsubdir/x/y/z , l’URI catturato è 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 il modo in cui funziona la directory.

Ciò che fa la base di riscrittura, è fornire una base del percorso URL ( non una base del percorso file) per qualsiasi percorso relativo nella destinazione della regola . Quindi dì che hai questa regola:

 RewriteRule ^foo$ bar.php [L] 

Il bar.php è un percorso relativo, al contrario di:

 RewriteRule ^foo$ /bar.php [L] 

dove /bar.php è un percorso assoluto. Il percorso assoluto sarà sempre la “radice” (nella struttura delle directory sopra). Ciò significa che indipendentemente dal fatto che la regola sia nella “root”, “subdir1”, “subsubdir”, ecc., /bar.php percorso /bar.php sempre mappato su 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 , ti viene servito http://example.com/bar.php . Ma se quella regola è nella directory “subdir1” e vai a http://example.com/subdir1/foo , ti viene servito http://example.com/subdir1/bar.php . ecc. Questo a volte funziona e talvolta no, come dice la documentazione, dovrebbe essere richiesto per i percorsi relativi, ma la maggior parte delle volte sembra funzionare. Tranne quando stai reindirizzando (usando la bandiera R , o implicitamente perché hai un http://host nella destinazione della regola). Ciò significa questa regola:

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

se è nella directory “subdir2” e vai a http://example.com/subdir2/foo , mod_rewrite scambierà il percorso relativo come percorso file invece di percorso URL e, a causa della bandiera R , tu finirà per essere reindirizzato a qualcosa di simile: http://example.com/var/www/localhost/htdocs/subdir1 . Che ovviamente non è quello che vuoi.

È qui RewriteBase entra in gioco RewriteBase . 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”, andando a http://example.com/subdir2/subsubdir/foo mi servirà effettivamente http://example.com/blah/bar.php . Il “bar.php” viene aggiunto alla fine della base. In pratica, questo esempio non è solitamente quello che vuoi, perché non puoi avere basi multiple nello stesso contenitore di directory o nel file htaccess.

Nella maggior parte dei casi, è usato 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”.

Ciò consente in parte di rendere le tue regole portatili, in modo da poterle rilasciare in qualsiasi directory e solo modificare la base anziché un gruppo di regole. Ad esempio se tu avessi:

 RewriteEngine On RewriteRule ^foo$ /subdir1/bar.php [L] RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L] RewriteRule ^blah2$ /subdir1/blah2.php [L] ... 

in modo tale che andare su http://example.com/subdir1/foo serva http://example.com/subdir1/bar.php ecc. E dire che hai deciso di spostare tutti quei file e queste regole nella directory “subsubdir” . Invece di modificare ogni istanza di /subdir1/ a /subdir2/subsubdir/ , potresti avere solo 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 avuto bisogno di spostare quei file e le regole in un’altra directory, cambia semplicemente la base:

 RewriteBase /subdir2/subsubdir/ 

e questo è tutto.

AFAIK, RewriteBase è usato solo per correggere casi in cui mod_rewrite è in esecuzione in un file .htaccess non nella radice di un sito e indovina il percorso web sbagliato (al contrario del percorso del file system) per la cartella in cui è in esecuzione. Quindi, se tu avere una RewriteRule in un file .htaccess in una cartella che si mappa in http://example.com/myfolder che puoi utilizzare:

 RewriteBase myfolder 

Se mod_rewrite non funziona correttamente.

Cercare di usarlo per ottenere qualcosa di insolito, piuttosto che risolvere questo problema, sembra una ricetta per diventare molto confuso.

RewriteBase è utile solo in situazioni in cui è ansible inserire un .htaccess nella radice del proprio sito. Altrimenti, potrebbe essere meglio posizionare i diversi file .htaccess in diverse directory del tuo sito e omettere completamente la direttiva RewriteBase.

Ultimamente, per siti complessi, li ho eliminati, perché rende la distribuzione dei file dai test per vivere solo un ulteriore passaggio complicato.

Quando sviluppo, si trova su un dominio diverso all’interno di una cartella. Quando prendo un sito dal vivo, quella cartella non esiste più. L’utilizzo di RewriteBase mi consente di utilizzare lo stesso file .htaccess in entrambi gli ambienti.

Quando vivi:

 RewriteBase / # RewriteBase /dev_folder/ 

Durante lo sviluppo:

 # RewriteBase / RewriteBase /dev_folder/ 

La spiegazione più chiara che ho trovato non era negli attuali documenti Apache 2.4, ma nella versione 2.0 .

 # /abc/def/.htaccess -- per-dir config file for directory /abc/def # Remember: /abc/def is the physical path of /xyz, ie, the server # has a 'Alias /xyz /abc/def' directive eg RewriteEngine On # let the server know that we were reached via /xyz and not # via the physical path prefix /abc/def RewriteBase /xyz 

Come funziona? Per voi hacker di apache, questo documento 2.0 continua a fornire “informazioni dettagliate sui passaggi di elaborazione interni”.

Lezione appresa: sebbene sia necessario conoscere le “correnti”, le gemme possono essere trovate negli annali.

Questo comando può impostare in modo esplicito l’URL di base per le tue riscritture. Se desideri iniziare nella radice del tuo dominio, includerai la seguente riga prima del tuo RewriteRule:

 RewriteBase / 

Credo che questo estratto dalla documentazione di Apache integri bene le risposte precedenti:

Questa direttiva è necessaria quando si utilizza un percorso relativo in una sostituzione in contesto per directory (htaccess) a meno che non si verifichi una delle seguenti condizioni:

  • La richiesta originale e la sostituzione sono sotto DocumentRoot (diversamente da essere raggiungibile con altri mezzi, come Alias).

  • Il percorso del file system nella directory contenente RewriteRule, suffisso dalla relativa sostituzione, è valido anche come percorso URL sul server (questo è raro).

Come accennato in precedenza, in altri contesti è utile solo ridurre la regola. Inoltre, come accennato in precedenza, è ansible ottenere la stessa cosa posizionando il file htaccess nella sottodirectory.