2011-10-14 10 views
9

Sto cercando di ottenere un reindirizzamento URL di base per pretty-URL, e a causa di immagini, CSS ecc. Che risiedono nello stesso percorso ho bisogno di assicurarmi che se l'URL è accesso senza una barra finale, viene aggiunto automaticamente.Come fare un reindirizzamento mod_rewrite all'URL relativo

Questo funziona bene se metto l'URL assoluto come questo:

RewriteRule ^myParentDir/([A-Z0-9_-]+)$ http://www.mydomain.com/myParentDir/$1/ [R,nc,L] 

Ma se cambiare questo ad un URL relativo, in modo che non devo cambiarlo ogni volta che mi muovo le cose in cartelle , semplicemente non funziona.

Questi sono quelli che ho provato e tutto non funzionano, o mi reindirizzare al percorso effettivo directory interna del server come/public_html/...:

RewriteRule ^myParentDir/([A-Z0-9_-]+)$ ./myParentDir/$1/ [R,nc,L] 

RewriteRule ^myParentDir/([A-Z0-9_-]+)$ myParentDir/$1/ [R,nc,L] 

Qual è il modo giusto di fare una reindirizzamento URL in modo che, se l'utente inserisce qualcosa di simile:

http://www.mydomain.com/somedir/myVirtualParentDir/myVirtualSubdir 

lui viene reindirizzato a (via HTTP 301 o 302):

http://www.mydomain.com/somedir/myVirtualParentDir/myVirtualSubdir/ 

Grazie.

MODIFICA: Aggiunta di ulteriori dettagli perché non sembra essere chiaro. Diciamo che sto implementando una galleria, e voglio avere degli URL piuttosto che usano mod_rewrite. Quindi, mi piacerebbe avere gli URL come segue:

http://www.mydomain.com/somedir/galleries/cats 

che mostra le miniature di gatti, mentre:

http://www.mydomain.com/somedir/galleries/cats/persian 

che mostra un'immagine dalle miniature di tutti i gatti, di nome persiano. Quindi, in realtà la struttura di directory fisica e riscrittura sarebbe la seguente:

http://www.domain.com/somedir/gallery.php?category=cats&image=persian 

Quindi quello che voglio fare è mettere un file .htaccess nella/somedir che cattura tutte le richieste effettuate a/Gallerie ed a seconda della sottodirectory virtuali segue, li usano come segnaposto nel riscrittura, con regole 2 di riscrittura:

RewriteRule ^galleries/(A-Z0-9_-]+)/$ ./gallery.php?category=$1 [nc] 
RewriteRule ^galleries/(A-Z0-9_-]+)/+([A-Z0-9_-]+)$ ./gallery.php?category=$1&image=$2 [nc] 

Ora il problema è che lo script galleria, infatti, ha bisogno di qualche CSS, Javascript e immagini, che si trova a http://www.domain.com/somedir/css, http://www.domain.com/somedir/js, e http://www.domain.com/somedir/images rispettivamente.

Non voglio hardcode alcun URL assoluto, quindi CSS, JS e immagini saranno riferiti a utilizzando URL relativi, (./css, ./js, ./images ecc.). Così posso fare URL riscrittura come segue:

RewriteRule ^galleries/[A-Z0-9_-]+/css/(.*)$ ./css/$1 [nc] 

Il problema è che, poiché http://www.domain.com/somedir/galleries/cats è una directory virtuale, quanto sopra funziona solo se l'utente digita:

http://www.domain.com/somedir/gallaries/cats/ 

Se l'utente omette la barra finale mod_dir non lo aggiungerà perché in realtà questa directory non esiste realmente.

Se metto una riscrittura di reindirizzamento con l'URL assoluto funziona:

RewriteRule ^galleries/([A-Z0-9_-]+)$ http://www.mydomain.com/subdir/galleries/$1/ [R,nc,L] 

Ma io non voglio avere il prefisso URL hardcoded perché voglio essere in grado di mettere questo su qualsiasi dominio che voglio in qualunque sottodirectory che voglio, quindi ho provato questo:

RewriteRule ^galleries/([A-Z0-9_-]+)$ galleries/$1/ [R,nc,L] 

Ma invece si reindirizza a:

http://www.mydomain.com/home/myaccount/public_html/subdir/galleries/theRest 

che ovviamente non è quello che voglio.

EDIT: Ulteriori chiarimenti

La soluzione che sto cercando è quello di evitare hardcoding il nome di dominio o percorsi delle cartelle nel file .htaccess. Sto cercando una soluzione in cui se impacchetta il file .htaccess con il resto degli script e delle risorse, ovunque l'utente la decomprimi sul proprio server web, funziona immediatamente. Tutto funziona così a prescindere da questo problema di trailing finale.

Quindi qualsiasi soluzione che implichi l'hardcoding della directory principale o del percorso del server web in .htaccess in alcun modo non è ciò che sto cercando.

+0

@DoktorJ Conviene la modifica al mio post risponde alla tua domanda? –

+0

Dovresti scegliere la risposta accettata, se qualcuno di questi è stato d'aiuto. – sjas

risposta

0

Non sono sicuro di comprendere perfettamente il problema.

Il reindirizzamento della barra finale viene eseguito automaticamente sulla maggior parte dell'installazione di Apache a causa del modulo mod_dir (il 99% della probabilità ha il modulo mod_dir).

Potrebbe essere necessario aggiungere:

DirectorySlash On 

Ma è il valore di default.

Così. Se si accede a foo/bar e la barra non è un file nella directory foo ma una sottodirectory, mod_dir esegue il reindirizzamento su foo/bar/.

L'unica cosa che ho saputo che potrebbe rompere questo è il Option Multiviews che sta forse cercando di trovare un bar.php, bar.php, bar.a-mime-extension-knwon-by-apache nella directory. Quindi potresti provare ad aggiungere:

Option -Multiviews 

E rimuovere tutti i rewriteRules. Se non ottieni questo comportamento predefinito di Apache, forse dovrai guardare la riscrittura mod, ma è come usare una bomba nucleare per uccidere un ragno. Le bombe nucleari potrebbero diventare abbastanza permissive da usare bene.

EDIT: Per il trailing problema barra con mod-rewrite è possibile controllare questo documentation howto, affermando questo dovrebbe funzionare:

RewriteEngine on 
RewriteBase /myParentDir/ 
RewriteCond %{REQUEST_FILENAME} -d 
RewriteRule ^(.+[^/])$   $1/ [R] 
+0

Grazie per la risposta. Tuttavia, ricorda che queste non sono directory effettive. Questi non esistono fisicamente e sono solo directory virtuali per URL carini. Quindi in realtà l'URL: http://www.mydomain.com/somedir/myVirtualParentDir non esiste. Senza di esso sto ricevendo invalidi i relativi collegamenti alle immagini ecc. – jbx

+0

Perché hai incluso il RewriteBase? È l'intero punto che voglio evitare. Non voglio hardcode il percorso nel mio .htaccess. Voglio qualcosa che funzioni in qualunque sub-dir l'ho messo. Non è diverso dal specificare il percorso completo come http://www.mydomain.com/myParentDir/ nel reindirizzamento, che non desidero. Il resto è esattamente lo stesso del mio problema originale, in cui $ 1/sta reindirizzando l'URL fisico effettivo a quello virtuale.Quello che stai suggerendo sarà semplicemente reindirizzare a fisico myParentDir/theRest anziché a/myVirtualDir/theRest. – jbx

+0

@jbx: leggi il link, questo deve essere messo nella directory di primo livello e funziona per tutte le sottodirectory secondarie. – regilero

4

Ecco una soluzione direttamente dal Apache Documentation (sotto "slash problema"):

RewriteCond %{REQUEST_FILENAME} -d 
RewriteRule ^(.+[^/])$   $1/ [R] 

Ecco a solution che mette alla prova la REQUEST_URI per una barra finale, poi aggiunge:

RewriteCond %{REQUEST_URI} !(/$|\.) 
RewriteRule (.+) http://www.example.com/$1/ [R=301,L] 

Ecco another solution che consente di esentare certi schemi REQUEST_URI:

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_URI} !example.php 
RewriteCond %{REQUEST_URI} !(.*)/$ 
RewriteRule ^(.*)$ http://domain.com/$1/ [L,R=301] 

auguriamo che questi aiuto. :)

1

Questo potrebbe lavoro:

RewriteRule ^myParentDir/[A-Z0-9_-]+$ %{REQUEST_URI}/ [NS,L,R=301] 

Tuttavia, non sono sicuro perché si pensa che è necessario questo a tutti. Basta fare la vostra regola di riscrittura file CSS/JS/immagini più o meno così:

RewriteRule ^galleries/([A-Za-z0-9_-]+/)*(css|js|images)/(.*)$ ./$2/$3 

e tutto dovrebbe funzionare bene, indipendentemente dal fatto che il browser richiede /somedir/galleries/css/whatever.css o /somedir/galleries/cats/css/whatever.css o addirittura /somedir/galleries/cats/persian/calico/css/whatever.css.

Ps. Un problema con questa regola è che ti impedisce di avere nomi di gallerie "css", "js" o "immagini". Si potrebbe voler risolvere il problema denominando tali directory virtuali come ".css", ".js" e ".images" o usando qualche altro schema di denominazione che non sia in conflitto con i nomi di galleria validi.

2

Questa regola dovrebbe aggiungere una barra finale a qualsiasi URL che non sia un file/directory reale (che è, credo, ciò di cui si ha bisogno poiché Apache di solito esegue il reindirizzamento automaticamente per le directory esistenti).

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^(.+[^/])$ $1/ [L,R=301] 

Edit:

Al fine di evitare che Apache da aggiungendo il percorso relativo alla radice del documento, è necessario utilizzare RewriteBase. Così, per esempio, nella cartella destinata ad essere root dell'applicazione, si aggiunge quanto segue, che sostituisce il percorso fisico:

RewriteBase/
+0

Sembra che il trucco per usare RewriteBase sia avere una * e * una barra finale iniziale; ad esempio, "/ foo /" invece di "/ foo" o "foo /". RewriteBase era ancora un po 'pignolo per me, ma alla fine ha funzionato. Grazie! –