Reindirizzamento, modifica URL o reindirizzamento da HTTP a HTTPS in Apache: tutto ciò che avresti sempre voluto sapere sulle regole Mod_Rewrite ma hai avuto paura di chiedere


264

Questa è una domanda canonica sul mod_rewrite di Apache.

La modifica di un URL di richiesta o il reindirizzamento degli utenti a un URL diverso da quello richiesto in origine viene effettuata utilizzando mod_rewrite. Ciò include cose come:

  • Modifica da HTTP a HTTPS (o viceversa)
  • Modifica di una richiesta in una pagina che non esiste più in una nuova sostituzione.
  • Modifica di un formato URL (come? Id = 3433 in / id / 3433)
  • Presentazione di una pagina diversa basata sul browser, basata sul referrer, basata su tutto il possibile sotto la luna e il sole.
  • Qualunque cosa tu voglia fare casino con l'URL

Tutto quello che avresti sempre voluto sapere sulle regole Mod_Rewrite ma hai avuto paura di chiedere!

Come posso diventare un esperto nello scrivere regole mod_rewrite?

  • Qual è il formato e la struttura fondamentali delle regole mod_rewrite?
  • Di quale forma / sapore delle espressioni regolari ho bisogno di avere una solida conoscenza di?
  • Quali sono gli errori / le insidie ​​più comuni quando si scrivono le regole di riscrittura?
  • Qual è un buon metodo per testare e verificare le regole mod_rewrite?
  • Ci sono implicazioni SEO o prestazionali delle regole mod_rewrite di cui dovrei essere a conoscenza?
  • Ci sono situazioni comuni in cui mod_rewrite potrebbe sembrare lo strumento giusto per il lavoro ma non lo è?
  • Quali sono alcuni esempi comuni?

Un posto dove mettere alla prova le tue regole

Il sito web del tester htaccess è un ottimo posto per giocare con le tue regole e testarle. Mostra anche l'output di debug in modo da poter vedere cosa corrisponde e cosa no.


9
L'idea alla base di questa domanda è quella di dare un percorso ravvicinato a tutte le infinite domande mod_rewrite che fanno impazzire i nostri utenti più regolari. Questo è molto simile a quello che è stato fatto con la subnetting su serverfault.com/questions/49765/how-does-subnetting-work .
Kyle Brandt,

1
Inoltre, non voglio davvero troppi voti su questa domanda , piuttosto dovrebbero andare alla risposta. Non voglio fare questo CW perché voglio assicurarmi che il poster ottenga pieno credito per ciò che spero sia la risposta mod_rewrite per porre fine a tutte le domande mod_rewrite .
Kyle Brandt,

4
Mi dispiace, ho annullato la domanda. ;-) Penso davvero che debba apparire (o vicino) nella parte superiore delle mod-rewritericerche / filtri dei tag.
Steven lunedì

Someone Else (tm) dovrebbe gestire i casi d'uso comuni. Non li conosco abbastanza bene per rendergli giustizia.
sysadmin1138

Forse questa domanda dovrebbe essere collegata al tag wiki di mod-rewrite per rendere il percorso ancora più breve.
Beldaz,

Risposte:


224

ordine di sintassi mod_rewrite

mod_rewrite ha alcune regole di ordinamento specifiche che influenzano l'elaborazione. Prima di fare qualsiasi cosa, la RewriteEngine Ondirettiva deve essere data in quanto ciò attiva l'elaborazione mod_rewrite. Questo dovrebbe essere prima di qualsiasi altra direttiva di riscrittura.

RewriteCondprecedente RewriteRulerende quella UNA soggetta al condizionale. Le seguenti RewriteRules verranno elaborate come se non fossero soggette a condizioni.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html

In questo semplice caso, se il referrer HTTP proviene da serverfault.com, reindirizza le richieste del blog a pagine speciali serverfault (siamo proprio così speciali). Tuttavia, se il blocco sopra aveva una riga RewriteRule aggiuntiva:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg         $/blog/$1.sf.jpg

Tutti i file .jpg andrebbero alle pagine speciali di serverfault, non solo quelle con un referrer che indica che provengono da qui. Questo chiaramente non è l'intento di come sono scritte queste regole. Potrebbe essere fatto con più regole RewriteCond:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

Ma probabilmente dovrebbe essere fatto con qualche sintassi di sostituzione più complicata.

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

Il RewriteRule più complesso contiene i condizionali per l'elaborazione. L'ultimo tra parentesi (html|jpg)indica a RewriteRule di corrispondere per uno htmlo jpg, e di rappresentare la stringa corrispondente come $ 2 nella stringa riscritta. Questo è logicamente identico al blocco precedente, con due coppie RewriteCond / RewriteRule, lo fa solo su due righe anziché su quattro.

Più righe RewriteCond sono implicitamente ANDed e possono essere esplicitamente ORed. Per gestire i referrer da ServerFault e Super User (OR esplicito):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)    [OR]
RewriteCond %{HTTP_REFERER}                ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

Per servire le pagine riferite a ServerFault con i browser Chrome (AND implicito):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT}             ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

RewriteBaseè anche un ordine specifico in quanto specifica come le seguenti RewriteRuledirettive gestiscono la loro elaborazione. È molto utile nei file .htaccess. Se utilizzato, dovrebbe essere la prima direttiva in "RewriteEngine on" in un file .htaccess. Prendi questo esempio:

RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

Questo sta dicendo a mod_rewrite che questo particolare URL che sta attualmente gestendo è arrivato tramite http://example.com/blog/ invece del percorso della directory fisica (/ home / $ Username / public_html / blog) e di trattarlo di conseguenza. Per questo motivo, RewriteRuleconsidera che l'inizio della stringa sia dopo il "/ blog" nell'URL. Ecco la stessa cosa scritta in due modi diversi. Uno con RewriteBase, l'altro senza:

RewriteEngine On

##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER}                                   ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg)     $1.sf.$2

##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

Come puoi vedere, RewriteBaseconsente di riscrivere le regole per sfruttare il percorso del contenuto del sito Web piuttosto che il server Web , il che può renderle più comprensibili a coloro che modificano tali file. Inoltre, possono ridurre le direttive, il che ha un fascino estetico.


Sintassi di corrispondenza RewriteRule

RewriteRule stesso ha una sintassi complessa per la corrispondenza delle stringhe. Tratterò le bandiere (cose come [PT]) in un'altra sezione. Poiché i amministratori di sistema imparano con l'esempio più spesso che leggendo una pagina man , darò degli esempi e spiegherò cosa fanno.

RewriteRule ^/blog/(.*)$    /newblog/$1

Il .*costrutto corrisponde a qualsiasi carattere singolo ( .) zero o più volte ( *). Racchiudendolo tra parentesi si dice che fornisce la stringa che è stata abbinata come variabile $ 1.

RewriteRule ^/blog/.*/(.*)$  /newblog/$1

In questo caso, il primo. * NON era racchiuso tra parentesi quindi non viene fornito alla stringa riscritta. Questa regola rimuove un livello di directory dal nuovo sito blog. (/blog/2009/sample.html diventa /newblog/sample.html).

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$2

In questo caso, la prima espressione tra parentesi imposta un gruppo corrispondente. Questo diventa $ 1, che non è necessario e quindi non utilizzato nella stringa riscritta.

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$1/$2

In questo caso, usiamo $ 1 nella stringa riscritta.

RewriteRule ^/blog/(20[0-9][0-9])/(.*)$   /newblog/$1/$2

Questa regola utilizza una sintassi di parentesi speciale che specifica un intervallo di caratteri . [0-9] corrisponde ai numeri da 0 a 9. Questa regola specifica gestirà gli anni dal 2000 al 2099.

RewriteRule ^/blog/(20[0-9]{2})/(.*)$  /newblog/$1/$2

Questo fa la stessa cosa della regola precedente, ma la parte {2} gli dice di far corrispondere il carattere precedente (un'espressione di parentesi in questo caso) due volte.

RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html   /newblog/$1/$2.shtml

Questo caso corrisponderà a qualsiasi lettera minuscola nella seconda espressione corrispondente e lo farà per il maggior numero possibile di caratteri. Il \.costrutto gli dice di trattare il periodo come un periodo reale, non il carattere speciale che è negli esempi precedenti. Tuttavia, si interromperà se il nome del file contiene trattini.

RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html  /newblog/$1/$2.shtml

Questo intrappola i nomi dei file con trattini. Tuttavia, poiché -è un carattere speciale nelle espressioni tra parentesi, deve essere il primo carattere nell'espressione.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Questa versione intrappola qualsiasi nome di file con lettere, numeri o il -carattere nel nome del file. Ecco come specificare più set di caratteri in un'espressione di parentesi.


RewriteRule flags

I flag sulle regole di riscrittura hanno una miriade di significati speciali e casi d'uso .

RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html  /newblog/$1/$2.shtml  [L]

La bandiera è [L]alla fine dell'espressione precedente. È possibile utilizzare più flag, separati da una virgola. La documentazione collegata descrive ciascuno di essi, ma eccoli comunque:

L = ultimo. Interrompere l'elaborazione di RewriteRules quando questa corrisponde. L'ordine conta!
C = Catena. Continua l'elaborazione del prossimo RewriteRule. Se questa regola non corrisponde, la regola successiva non verrà eseguita. Più su questo più tardi.
E = Imposta variabile ambientale. Apache ha varie variabili ambientali che possono influenzare il comportamento del web server.
F = proibito. Restituisce un errore 403-proibito se questa regola corrisponde.
G = Andato. Restituisce un errore 410 andato se questa regola corrisponde.
H = Gestore. Forza la richiesta a essere gestita come se fosse il tipo MIME specificato.
N = Avanti. Forza la regola a ricominciare da capo e ad abbinare nuovamente. STAI ATTENTO! Possono verificarsi dei loop.
NC = Nessun caso. permettejpgper abbinare sia jpg che JPG.
NE = Nessuna via di fuga. Impedisce la riscrittura di caratteri speciali (.? # & Etc) nei loro equivalenti in codice esadecimale.
NS = Nessuna richiesta secondaria. Se utilizzi le inclusioni lato server, ciò impedirà la corrispondenza con i file inclusi.
P = Proxy. Forza la regola ad essere gestita da mod_proxy. Fornisci in modo trasparente contenuto da altri server, perché il tuo server web lo recupera e lo serve nuovamente. Questa è una bandiera pericolosa, poiché una scritta male trasformerà il tuo server web in un proxy aperto e quello è male.
PT = Pass Through. Prendi in considerazione le dichiarazioni Alias ​​nella corrispondenza RewriteRule.
QSA = QSAppend. Quando la stringa originale contiene una query ( http://example.com/thing?asp=foo) aggiunge la stringa di query originale alla stringa riscritta. Normalmente sarebbe scartato. Importante per i contenuti dinamici.
R = Reindirizzamento. Fornire un reindirizzamento HTTP all'URL specificato. Può anche fornire il codice di reindirizzamento esatto [R = 303]. Molto simile a RedirectMatch, che è più veloce e dovrebbe essere usato quando possibile.
S = Salta. Salta questa regola.
T = Tipo. Specificare il tipo mime del contenuto restituito. Molto simile alla AddTypedirettiva.

Sai come ho detto che si RewriteCondapplica a una e una sola regola? Bene, puoi aggirare questo incatenando.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html     [C]
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

Poiché la prima RewriteRule ha il flag Chain, la seconda regola di riscrittura verrà eseguita quando la prima lo fa, ovvero quando viene abbinata la precedente regola RewriteCond. Comodo se le espressioni regolari di Apache fanno male al cervello. Tuttavia, il metodo all-in-one-line che indico nella prima sezione è più veloce dal punto di vista dell'ottimizzazione.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Questo può essere reso più semplice attraverso i flag:

RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html   /newblog/$1/$2.shtml   [NC]

Inoltre, alcuni flag si applicano anche a RewriteCond. In particolare, NoCase.

RewriteCond %{HTTP_REFERER}        ^https?://serverfault\.com(/|$)     [NC]

Corrisponderà a "ServerFault.com"


9
Molto bene. [riempimento]
EEAA

3
mod_rewritePrimer molto bello e regex. +1.
Steven lunedì

3
A volte è utile sapere che RewriteCondviene effettivamente elaborato dopo la RewriteRulecorrispondenza. Potresti voler dire "più avanti" più avanti nella parte superiore dove dici "RewriteCond che precede RewriteRule rende quella UNA soggetta al condizionale". Potresti voler menzionare che le regex sono espressioni regolari compatibili con Perl. Inoltre hai un apostrofo estraneo in "... la RewriteRule considera l'inizio della stringa ..."
Dennis Williamson,

2
RewriteRule ^/blog/.*/(.*)$ /newblog/$1non corrisponde al primo componente della directory - i riscrittori sono avidi per impostazione predefinita. /.*/(.*) corrisponde a entrambi / 1 / (2) / e / 1/2/3/4/5 / (6) /, quindi è necessario / [^ /] * / per corrispondere solo al PRIMO percorso componente.
adattamento

1
@ sysadmin1138, penso che questa risposta sia buona ma può essere migliore se elabori di più sulle bandiere E, N, NS, P, PT e S con esempi perché quelle bandiere non sono ovvie su come funzionano ecc.
Pacerier

39

Qual è il formato e la struttura fondamentali delle regole mod_rewrite?

Rimanderò alla risposta eccellente di sysadmin1138 su questi punti.

Di quale forma / sapore delle espressioni regolari ho bisogno di avere una solida conoscenza di?

Oltre all'ordine della sintassi, alla corrispondenza della sintassi / alle espressioni regolari e ai flag RewriteRule delineati da sysadmin1138, credo che sia necessario menzionare che mod_rewrite espone le variabili di ambiente Apache in base alle intestazioni della richiesta HTTP e alla configurazione di Apache.

Vorrei raccomandare il tutorial di debug mod_rewrite di AskApache per un elenco completo di variabili che potrebbero essere disponibili per mod_rewrite.

Quali sono gli errori / le insidie ​​più comuni quando si scrivono le regole di riscrittura?

La maggior parte dei problemi con RewriteRule derivano da un fraintendimento della sintassi / incapacità di PCRE di sfuggire correttamente a caratteri speciali o di una mancanza di conoscenza del contenuto delle variabili utilizzate per la corrispondenza.

Problemi tipici e risoluzione dei problemi raccomandati:

  • 500 - Errore interno del server - Rimuovere i controlli del carrello di Windows nei file di configurazione, se presenti, assicurarsi che mod_rewrite sia abilitato (avvolgere le direttive in modo IfModulecondizionale per evitare questo scenario), controllare la sintassi della direttiva, commentare le direttive fino all'identificazione del problema
  • Ciclo di reindirizzamento - Usa RewriteLog e RewriteLogLevel, commenta le direttive fino a quando non viene identificato il problema

Qual è un buon metodo per testare e verificare le regole mod_rewrite?

Innanzitutto, guarda il contenuto delle variabili d'ambiente che prevedi di abbinare - se hai installato PHP, questo è semplice come aggiungere il seguente blocco alla tua applicazione:

<?php
  var_dump($_SERVER);
?>

... quindi scrivi le tue regole (preferibilmente per i test su un server di sviluppo) e annota qualsiasi corrispondenza o attività incoerente nel tuo file ErrorLog di Apache .

Per regole più complesse, utilizzare la RewriteLogdirettiva mod_rewrite per registrare l'attività su un file e impostareRewriteLogLevel 3

Ci sono implicazioni SEO o prestazionali delle regole mod_rewrite di cui dovrei essere a conoscenza?

AllowOverride allinfluisce sulle prestazioni del server poiché Apache deve verificare la presenza di .htaccessfile e analizzare le direttive con ogni richiesta - se possibile, mantenere tutte le direttive nella configurazione VirtualHost per il proprio sito o abilitare le .htaccesssostituzioni solo per le directory che ne hanno bisogno.

Le Linee guida per i webmaster di Google dichiarano esplicitamente: "Non ingannare i tuoi utenti o presentare contenuti diversi ai motori di ricerca di quelli che visualizzi agli utenti, che viene comunemente definito" occultamento "." - evita di creare direttive mod_rewrite che filtrano i robot dei motori di ricerca.

I robot dei motori di ricerca preferiscono un contenuto 1: 1: mappatura URI (questa è la base per classificare i collegamenti al contenuto) - se stai usando mod_rewrite per creare reindirizzamenti temporanei o stai offrendo lo stesso contenuto in più URI, considera di specificare un URI canonico all'interno i tuoi documenti HTML.

Ci sono situazioni comuni in cui mod_rewrite potrebbe sembrare lo strumento giusto per il lavoro ma non lo è?

Questo è un argomento enorme (e potenzialmente controverso) a sé stante - migliore (IMHO) per affrontare gli usi caso per caso e consentire ai richiedenti di determinare se le risoluzioni suggerite sono appropriate alle loro esigenze.

Quali sono alcuni esempi comuni?

I trucchi e i suggerimenti mod_rewrite di AskApache coprono quasi tutti i casi d'uso comuni che compaiono regolarmente, tuttavia, la soluzione "corretta" per un determinato utente può dipendere dalla raffinatezza della configurazione dell'utente e dalle direttive esistenti (motivo per cui è generalmente un buona idea per vedere quali altre direttive ha un utente in atto ogni volta che sorge una domanda mod_rewrite).


Grazie per il link AskApache. È quello che stavo cercando!
sica07,

Il pagliaccio AskApache non è ufficialmente supportato dall'ASF. Gran parte di ciò che dice è discutibile o chiaramente sbagliato.
adattamento

@adaptr Si prega di condividere le risorse superiori di cui apparentemente siete a conoscenza.
danlefree

"situazioni comuni in cui mod_rewrite potrebbe sembrare lo strumento giusto per il lavoro ma non lo è?" - reindirizzamenti semplici , in cui mod_rewrite non è già in uso. Usa mod_alias Redirecto RedirectMatchinvece. Vedi anche i documenti di Apache: quando non usare mod_rewrite
MrWhite

21

Come molti amministratori / sviluppatori ho combattuto la complessità delle regole di riscrittura per anni e non sono soddisfatto della documentazione esistente di Apache, quindi ho deciso come progetto personale di approfondire il modo mod_rewritein cui funziona e interagisce con il resto di Apache core, quindi negli ultimi mesi ho strumentato i casi di test con strace+ drill nel codice sorgente per ottenere un controllo su tutto questo.

Ecco alcuni commenti chiave che devono essere considerati dagli sviluppatori di regole di riscrittura:

  • Tuttavia, alcuni aspetti della riscrittura sono comuni alla configurazione del server, host virtuale, directory, elaborazione .htaccess
  • Alcune elaborazioni sono molto diverse per la configurazione principale (configurazione server, host virtuale e directory) rispetto all'elaborazione PerDir ( .htaccess).
  • Peggio ancora perché l'elaborazione PerDir può innescare quasi indiscriminatamente il ciclo INTERNAL REDIRECT, gli elementi di configurazione di root devono essere scritti consapevoli che tale elaborazione PerDir può innescare questo.

Vorrei dire che per questo è quasi necessario dividere le comunità di utenti riscritte in due categorie e trattarle come completamente separate:

  • Quelli con accesso root alla configurazione di Apache . Si tratta in genere di un amministratore / sviluppatore con un server / VM dedicato all'applicazione e il messaggio qui è abbastanza semplice: evitare di usare i .htaccessfile se possibile; fai tutto nella configurazione del tuo server o vhost. Il debug è abbastanza semplice poiché lo sviluppatore può impostare il debug e ha accesso ai file rewrite.log.

  • Utenti di un servizio hosted condiviso (SHS) .

    • Tali utenti devono utilizzare l' .htaccesselaborazione / Perdir in quanto non sono disponibili alternative.
    • Peggio ancora, il livello di abilità di tali utenti (per quanto riguarda l'uso della logica ladder basata su regexp di mod_rewrite) è generalmente significativamente inferiore rispetto agli amministratori esperti.
    • Apache e i provider di hosting non offrono supporto di debug / diagnostica. Le uniche informazioni diagnostiche sono un reindirizzamento riuscito, un reindirizzamento all'URI errato. o un codice di stato 404/500. Questo li lascia confusi e indifesi.
    • Apache è estremamente debole e spiega come funziona la riscrittura per questo caso d'uso. Ad esempio, non fornisce una chiara spiegazione di quale .htaccessfile PerDir è selezionato e perché. Non spiega le complessità del ciclismo PerDir e come evitarlo.

Esiste forse una terza comunità: amministrare e supportare il personale dei fornitori di SHS che finisce con un piede in entrambi i campi e deve subire le conseguenze di cui sopra.

Ho scritto un paio di post di blog in stile articolo (ad es. Di più sull'uso delle regole di riscrittura nei file .htaccess ) che trattano molti punti dettagliati che non ripeterò qui per non rendere questo post breve. Ho il mio servizio condiviso e supporto alcuni progetti FLOSS dedicati e VM. Ho iniziato a utilizzare una VM LAMP standard come veicolo di prova per il mio account SHS, ma alla fine ho trovato meglio fare una VM mirror corretta (descritta qui ).

Tuttavia, in termini di come la comunità di amministratori dovrebbe supportare gli .htaccessutenti, ritengo che dobbiamo sviluppare e offrire:

  • Una descrizione coerente di come funziona effettivamente il sistema di riscrittura nell'elaborazione PerDir
  • Una serie di linee guida / migliori pratiche su come scrivere .htaccessregole di riscrittura
  • Un semplice parser di script di riscrittura basato sul Web simile a quello dei parser html del W3C, ma grazie al quale gli utenti possono inserire URI di test o testare i vettori dello stesso e ottenere un registro immediato del flusso logico di riscrittura /
  • Suggerimenti su come ottenere la diagnostica integrata dalle regole (ad es

    • Utilizzare [E=VAR:EXPR]sfruttando il fatto che EXPRespanderà i riferimenti indietro ($ N o% N) per renderli disponibili come diagnostica per lo script di destinazione.
    • Se ordini topicamente le tue regole di riscrittura usando i flag [OR], [C], [SKIP] e [L] in modo che l'intero schema di riscrittura funzioni senza la necessità di sfruttare il reindirizzamento interno, puoi aggiungere quanto segue come regola 1 per evitare tutte le seccature cicliche:

      RewriteCond %{ENV:REDIRECT_STATUS} !=""
      RewriteRule .  -  [L]
      

Questo è ben documentato. Perché dici che la documentazione non spiega questo?
adattamento

2
Tutto quello che devi fare è iscriverti agli .htaccessargomenti e vedrai. La maggior parte dei principianti si confonde irrimediabilmente: molti di questi hanno la loro prima esperienza di servizio LAMP e mod_rewrite su un servizio condiviso e quindi non hanno accesso root alle configurazioni di sistema / vhost e devono usare l'elaborazione per dir attraverso i .htaccessfile. Ci sono differenze importanti che il principiante deve "sanguinare". Mi considererei un potente utente e sto ancora scoprendo sottigliezze. Come ho già detto, ho dovuto usare la scansione di strace e di codice sorgente per risolvere alcuni aspetti. Non sarebbe necessario. :-(
TerryE

Sono totalmente d'accordo. "Dobbiamo dividere le comunità di utenti di riscrittura in due categorie e trattarle come completamente separate." Alcuni utenti utilizzano l'hosting condiviso e devono fare affidamento su .htaccess, che è terribilmente fragile, complicato e confuso, anche per gli esperti. Ho ancora problemi.
Ryan

15

Utilizzo di rewritemap

Ci sono molte cose che puoi fare con le riscritture. Le riscritture vengono dichiarate utilizzando la direttiva Rewritemap e possono quindi essere utilizzate sia nelle valutazioni RewritCond, sia nelle sottosezioni RewriteRule.

La sintassi generale per RewriteMap è:

RewriteMap MapName MapType:MapSource

Per esempio:

RewriteMap examplemap txt:/path/to/file/map.txt

È quindi possibile utilizzare il nome mappa per costrutti come questo:

${examplemap:key}

La mappa contiene coppie chiave / valore. Se viene trovata la chiave, il valore viene sostituito. Le mappe semplici sono solo file di testo semplice, ma è possibile utilizzare mappe hash e persino query SQL. Maggiori dettagli sono nei documenti:

http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap

Stringhe senza escape.

Esistono quattro mappe interne che è possibile utilizzare per eseguire alcune manipolazioni. Le stringhe particolarmente senza escape possono tornare utili.

Ad esempio: voglio testare la stringa "café" nella stringa di query. Tuttavia, il browser sfuggirà a questo prima di inviarlo al mio server, quindi dovrò capire qual è la versione dell'URL con escape per ogni stringa che desidero abbinare, oppure posso semplicemente annullare l'escape ...

RewriteMap unescape int:unescape

RewriteCond %{QUERY_STRING}  (location|place)=(.*)
RewriteCond ${unescape:%2}   café
RewriteRule ^/find/$         /find/1234? [L,R]

Nota come utilizzo RewriteCond per catturare l'argomento in punta del parametro della stringa di query e quindi utilizzare la mappa nel secondo rewriteCond per annullare l'eliminazione. Questo viene quindi confrontato. Nota anche come ho bisogno di noi% 2 come chiave nella riscrittura, poiché% 1 conterrà "posizione" o "luogo". Quando si utilizzano le parentesi per raggruppare i motivi, questi verranno anche catturati, sia che si pianifichi di utilizzare il risultato della cattura o meno ...


L'ultima frase non è del tutto vera. Il mod_rewritemotore regexp supporta gruppi non di acquisizione come (?:location|place)e questo avrà solo una cattura nell'esempio.
TerryE

12

Quali sono gli errori / le insidie ​​più comuni quando si scrivono le regole di riscrittura?

Una trappola molto semplice è quando si riscrivono gli URL che alterano il percorso apparente, ad esempio da /base/1234/index.htmla /base/script.php?id=1234. Eventuali immagini o CSS con percorsi relativi alla posizione dello script non verranno trovati dal client. Una serie di opzioni per risolvere questo problema è disponibile in questa domanda .


1
Grazie per il link Soprattutto quando lavoro con altri membri del team che non hanno familiarità con la riscrittura, trovo che l'aggiunta di un <base>tag sia la più facile da seguire e permetta comunque percorsi relativi.
Kontur,
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.