Beispiel für die aktuelle Dateistruktur:
example.com/foo.php
example.com/bar.html
example.com/directory/
example.com/directory/foo.php
example.com/directory/bar.html
example.com/cgi-bin/directory/foo.cgi*
Ich möchte HTML-, PHP- und CGI-Erweiterungen aus entfernen und dann den abschließenden Schrägstrich am Ende von URLs erzwingen. So könnte es aussehen:
example.com/foo/
example.com/bar/
example.com/directory/
example.com/directory/foo/
example.com/directory/bar/
example.com/cgi-bin/directory/foo/
Ich bin sehr frustriert, weil ich 17 Stunden lang direkt nach einer Lösung gesucht und mehr als ein paar hundert Seiten in verschiedenen Blogs und Foren besucht habe. Ich mache keine Witze. Ich glaube, ich habe meine Nachforschungen angestellt.
Hier ist der Code, der sich gerade in meiner .htaccess-Datei befindet:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(([^/]+/)*[^./]+)/$ $1.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
Wie Sie sehen können, entfernt dieser Code nur .html (und ich bin nicht sehr zufrieden damit, weil ich denke, dass es viel einfacher gemacht werden könnte). Ich kann die Erweiterung aus PHP-Dateien entfernen, wenn ich sie über .htaccess in .html umbenenne, aber das ist nicht das, was ich will. Ich möchte es gerade entfernen. Dies ist das erste, was ich nicht tun kann.
Das zweite ist eigentlich sehr nervig. Meine .htaccess-Datei mit dem obigen Code wird .html/
zu jeder nachfolgend eingegebenen Zeichenfolge hinzugefügt example.com/directory/foo/
. Wenn ich also eingebe example.com/directory/foo/bar
(offensichtlich /bar
nicht vorhanden, da foo
es sich um eine Datei handelt), anstatt nur die Nachricht anzuzeigen, dass die Seite nicht gefunden wurde, konvertiert sie diese in example.com/directory/foo/bar.html/
, sucht dann einige Sekunden lang nach einer Datei und zeigt dann die nicht gefundene Nachricht an. Das ist natürlich schlechtes Benehmen.
Also noch einmal, ich brauche den Code in .htaccess, um die folgenden Dinge zu tun:
- Entfernen Sie die HTML-Erweiterung
- Entfernen Sie die .php-Erweiterung
- Entfernen Sie die .cgi-Erweiterung
- Erzwingen Sie den abschließenden Schrägstrich am Ende von URLs
- Anforderungen sollten sich korrekt verhalten (keine zusätzlichen Schrägstriche oder Erweiterungen zu Zeichenfolgen hinzufügen, wenn Datei oder Verzeichnis auf dem Server nicht vorhanden sind).
- Der Code sollte so einfach wie möglich sein
@ Kronbernkzion ausgezeichnet. Das einzige Problem, das ich jetzt habe, ist, dass 404s nicht richtig zu funktionieren scheinen und mich zu einem wirklich funky Ort führen. Ich kann nicht einmal eine absolute 404-Weiterleitung verwenden.
ErrorDocument 404 http://www.google.com
Bist du darauf gestoßen? Wie bist du daran vorbei gekommen?
Abgesehen von der 404-Umschreibung war der vollständige Code, den ich verwendet habe:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)/$ $1.html [L]
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)/$ $1.php [L]
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_FILENAME}\.cgi -f
RewriteRule (.*)/$ $1.cgi [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f [OR]
RewriteCond %{REQUEST_FILENAME}\.php -f [OR]
RewriteCond %{REQUEST_FILENAME}\.cgi -f
RewriteRule .* %{REQUEST_FILENAME}/ [R=301,L]
</IfModule>
quelle
/foo.html
und/bar.php
, werden Sie eine Regel haben , dass explizit paßt/foo/
zu/foo.html
und/bar/
zu/bar.php
? Oder benötigen Sie einen einzelnen generischen Eintrag, der/foo/
mit beiden/foo.html
ODER übereinstimmt/foo.php
(je nachdem, welcher vorhanden ist)?Antworten:
Also habe ich eine Reihe von Rewrite-Regeln geschrieben, die das getan haben, was Sie wollten, aber meine Website sind völlig kaputt gegangen. Mir wurde klar, dass das, was Sie wollen, wahrscheinlich nicht das ist, was Sie brauchen. Das Hinzufügen von abschließenden Schrägstrichen am Ende aller URLs beeinträchtigt die Semantik der URL erheblich, da Sie nicht mehr auf die Datei,
/foo
sondern auf die Inhaltsliste des Verzeichnisses zugreifen/foo/
.Zum Beispiel:
Wechsel
/mypage
zu/mypage/
werden wahrscheinlich brechen alle relativen Links. Wenn Sie auf eine Javascript-Datei verweisen<script src="myscript.js">
, anstatt danach zu suchen/myscript.js
, sucht der Browser nach/mypage/myscript.js
. Sie müssten Ihre Quelle ändern, um zu lesen,<script src="../myscript.js">
welche 1) für den Autor keinen Sinn ergibt und 2) hässlicher aussieht, als keine abschließenden Schrägstriche zu haben.Als Referenz:
würde nur PHP-, CGI- und HTML-Erweiterungen ändern , aber eine bessere Idee wäre, die Apache2-Inhaltsverhandlung (mit MultiViews) zu verwenden.
Bearbeiten:
Der ursprüngliche Code. Oder zumindest ein Teil davon. Ich habe es gebrochen und dann auf das oben Gesagte reduziert, und jetzt kann ich mich nicht mehr genau erinnern, was ich getan habe. Aber es macht alles außer dem Entfernen nachfolgender Erweiterungen.
Sie können mir eine E-Mail an mazin (at) aztekera.com senden, wenn Sie möchten.
quelle
Mazin, vielen Dank für Ihre Hilfe und dafür, dass Sie mir die richtige Richtung gezeigt haben! Der folgende Code dient zum Entfernen der Erweiterungen .html, .php und .cgi sowie zum Erzwingen von abschließenden Schrägstrichen am Ende von URLs. Der endgültige Arbeitscode sieht folgendermaßen aus:
Ich bin sehr zufrieden mit dem Ergebnis.
Ich habe Mazin eine iTunes-Geschenkkarte im Wert von 50 US-Dollar als großes Dankeschön für Ihre Hilfe geschickt.
quelle
Klingt so, als würden Sie versuchen, etwas Ähnliches wie eine REST-kompatible URL-Implementierung zu tun.
Ich habe dies bereits auf SO gesehen, hier: /programming/395650/url-mapping-in-php
Möglicherweise können Sie die beiden Top-Lösungen dort an Ihre Bedürfnisse anpassen.
quelle
Wenn Sie das genaue Format jeder URL kennen, die Sie benötigen, ist dies ziemlich einfach. Wenn Sie jedoch nicht wissen, zu welcher Erweiterung Sie passen müssen, bin ich mir ziemlich sicher, dass dies unmöglich ist.
Wenn Sie beispielsweise WISSEN, dass Sie
foo.html
undbar.php
- haben und dass dies/foo/
mit foo.html übereinstimmen muss und Sie wissen, dass/bar
/ übereinstimmen/bar.php
muss, kann dies getan werden. Wenn jedoch jemand hochlädt/cat.php
und jemand eintritt,/cat/
weiß das System nicht, ob es übereinstimmen muss,/cat.html
oder/cat.php
- Sie müssen es mitteilen. Wenn Sie sich nur mit einer Erweiterung befassen würden, wäre das nicht so schlimm, Sie könnten sie einfach auf jede Anfrage anwenden.Um
/foo/
es/foo.html
dann umzuschreiben , würden Sie tun:RewriteRule (/foo/) /foo.html
Einfach
Wenn Sie jede Anforderung einer SINGLE-Erweiterung zuordnen möchten, können Sie Folgendes tun:
RewriteRule (/foo/)(.*)(/) /foo/$2.html
Dies wird Karte
/foo/mypage/
zu/foo/mypage.html
(und Sie können dies auf Multi-Level - Verzeichnis erweitern einige RegEx-fu verwenden , die über meine Gehaltsstufe ist).Nun, ich weiß eigentlich nicht, wonach Sie fragen. Bitte kommentieren Sie meine Antwort oder aktualisieren Sie Ihre Frage, wenn diese Regeln für Sie nicht funktionieren.
- Bearbeiten -
Ich habe gerade Ihre Antwort auf meinen Kommentar oben bemerkt. Mit .htaccess können Sie auf keinen Fall das tun, was Sie möchten, da .htaccess nicht überprüfen kann, ob bestimmte Dateianforderungen vorhanden sind. Woher weiß es, dass
/foo/
das sein soll/foo.html
oder/foo.php
oder/foo.cgi
? Ihr einziger Ausweg wird sein:1) Leiten Sie JEDE Anfrage über eine einzelne.php-Datei, die dann wissen / prüfen kann, ob die .php- oder .html- oder .cgi-Version der Datei vorhanden ist, und leiten Sie Ihre Anfrage auf diese Weise weiter
2) Erstellen Sie eine .htaccess-Datei, die einen Eintrag für jede einzelne eindeutige Datei enthält
quelle