
Ich schreibe die Apache 2.4-Konfiguration neu, die ich vom alten Entwicklungsteam erhalten habe.
Ich habe ungefähr 200 Zeilen mit ähnlicher Konfiguration und verstehe nicht, nach welchem Prinzip ich diesen Code ändern muss, um ihn vom .htaccess
virtuellen Host zu verschieben.
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^(.*)$ /$1/ [R,L,NC]
Wenn ich sie einfach auf den virtuellen Host verschiebe, stürzt meine Site an Stellen ab, die ich nicht verstehe.
Antwort1
Es hängt davon ab, wo im <VirtualHost>
Container Sie diese Anweisungen platzieren.
Wenn Sie einen Container verwenden <Directory>
(z. B. einenVerzeichnisKontext) undDeaktivieren .htaccess
überschreibt alles vollständig (sonst .htaccess
wird der <Directory>
Container überschrieben!), dann können Sie die Anweisungen im Wesentlichen so kopieren, wie sie sind (vorausgesetzt, der <Directory>
Container verweist auf dasselbe Verzeichnis wie die .htaccess
Datei).
<VirtualHost>
Wenn Sie diese Anweisungen jedoch direkt in den Container (außerhalb eines Containers) einfügen <Directory>
, d. h. in einemvirtueller HostKontext, dann müssen Sie einige Änderungen vornehmen. Dies liegt daran, dass die Anweisungen früher verarbeitet werden, bevor die Anforderung dem Dateisystem zugeordnet wird.
In den von Ihnen veröffentlichten Anweisungen wären nur zwei Änderungen erforderlich:
In einemvirtueller HostKontext
REQUEST_FILENAME
wurde die Servervariable noch nicht in eineDateiname. Es ist dasselbe wieREQUEST_URI
(also die angeforderte URL). Ihre Dateisystemprüfung wird also immer fehlschlagen und die Bedingung wird immer erfolgreich sein! Sie müssen entweder eine Vorausschau verwenden, z. B.%{LA-U:REQUEST_FILENAME}
, oder den absoluten Dateinamen selbst konstruieren, z. B.%{DOCUMENT_ROOT}%{REQUEST_URI}
. Beispiel:RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
In einemvirtueller HostKontext, der URL-Pfad, der mit dem
RewriteRule
Musterist root-relativ (beginnt mit einem Schrägstrich). In hingegen.htaccess
ist es relativ zum Verzeichnis, das die.htaccess
Datei enthält – abzüglich des Schrägstrichpräfixes. Die Regel würde also in ihrer vorliegenden Form zu einem doppelten Schrägstrich am Anfang des URL-Pfades führen, sie sollte stattdessen wie folgt umgeschrieben werden:RewriteRule ^/(.*)$ /$1/ [R,L]
(Die
NC
Flagge ist hier nicht erforderlich.)Oder (besser) verwenden Sie hier keine Rückreferenz, sondern die
REQUEST_URI
Servervariable (was natürlich.htaccess
auch funktionieren würde). Beispiel:RewriteRule ^ %{REQUEST_URI}/ [R,L]
(Beiseite:Dies sollte wahrscheinlich auch eine permanente 301-Umleitung sein (d. h.
R=301
). So wie es aussieht, wird dies standardmäßig eine temporäre 302-Umleitung sein. Ändern Sie die Umleitung jedoch erst dann in eine 301-Umleitung – wenn dies beabsichtigt ist –, wenn Sie bestätigt haben, dass es wie beabsichtigt funktioniert.)
Zusammengefasst würde das also zu:
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^/(.*)$ /$1/ [R,L]
Beiseite:
Das oben genannte kann sofort etwas optimiert werden, indem man die Dateisystemprüfung (die relativteuer) zur letzten Bedingung und Verschieben desZustanddas überprüft, ob die Anfrage nicht bereits mit einem Schrägstrich zur RewriteRule
Direktive endet. Außerdem werden die Regex-Untermuster (.*)
in jedem derBedingungensind nicht erforderlich. Daher könnte das Obige effizienter umgeschrieben werden:
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_URI} !^/application-module/
RewriteCond %{REQUEST_URI} !json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/ [NC]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule !/$ %{REQUEST_URI}/ [R,L]
Die Dateisystemprüfung kann möglicherweise vollständig entfernt werden, wenn Sie stattdessen Anforderungen ausschließen, die (scheinbar) eine Dateierweiterung enthalten. Dies kann jedoch von Ihrer Dateistruktur abhängen.
DerZustanddas überprüft, sieht so aus, als ob es wirklich nach der Dateierweiterung !json$
suchen sollte , also . (Das passt zu meinem obigen Kommentar über den Ausschluss.json
!\.json$
alleAnfragen, die eine „Dateierweiterung“ haben.)
Der ersteZustanddas prüft, ob die Abfragezeichenfolge leer ist, scheint ein wenig seltsam (da es beim Anhängen eines Schrägstrichs an den URL-Pfad nicht wirklich wichtig ist, ob eine Abfragezeichenfolge vorhanden ist oder nicht), aber ich nehme an, dass dies eine spezielle Anforderung sein muss?