Wie entferne ich Erweiterungen aus und erzwinge den abschließenden Schrägstrich am Ende von URLs?


7

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 /barnicht vorhanden, da fooes 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>

Ich fühle deinen Schmerz
Mark Henderson

Frage: Müssen diese Umschreiberegeln mit ALLEN Erweiterungen übereinstimmen? Zum Beispiel, wenn Sie /foo.htmlund /bar.php, werden Sie eine Regel haben , dass explizit paßt /foo/zu /foo.htmlund /bar/zu /bar.php? Oder benötigen Sie einen einzelnen generischen Eintrag, der /foo/mit beiden /foo.htmlODER übereinstimmt /foo.php(je nachdem, welcher vorhanden ist)?
Mark Henderson

Ich brauche einen einzigen generischen Eintrag. Nichts dateispezifisches, ich möchte nur Erweiterungen aus diesen drei Dateitypen entfernen.

@Kronbernkzion, ich habe meine Antwort aktualisiert. Ich glaube nicht, dass dir gefallen wird, was darin steht.
Mark Henderson

Es gibt keinen wirklichen Grund, einen abschließenden Schrägstrich zu verwenden. Schauen Sie sich zendesk.com an, die WordPress verwenden. Sie haben ihre Permaliks so konfiguriert, dass sie keinen abschließenden Schrägstrich verwenden. Ich habe das gleiche Setup auch für einige Domains verwendet und Google crawlt sie einwandfrei und sie sehen meiner Meinung nach besser aus als mit einem abschließenden Schrägstrich. Ich würde auf WP upgraden, wenn Sie können, und einfach 301 von Ihren alten statischen oder dynamischen Seiten auf die neuen WP-Seiten einrichten.
Anagio

Antworten:


6

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, /foosondern auf die Inhaltsliste des Verzeichnisses zugreifen /foo/.

Zum Beispiel:

Wechsel /mypagezu /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:

RewriteCond %{REQUEST_FILE}\.html -f
RewriteRule (.*)$ $1.html [L]

RewriteCond %{REQUEST_FILE}\.php -f
RewriteRule (.*)$ $1.php [L]

RewriteCond %{REQUEST_FILE}\.cgi -f
RewriteRule (.*)$ $1.cgi [L]

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.

# This block adds the trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond /your/web/directory%{REQUEST_URI}\.html -f [OR]
RewriteCond /your/web/directory%{REQUEST_URI}\.php -f [OR]
RewriteCond /your/web/directory%{REQUEST_URI}\.cgi -f
RewriteRule .* %{REQUEST_URI}/ [R=301,L]

# These blocks redirect /foo/ to /foo.html and so on
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond /your/web/directory%1\.html -f
RewriteRule (.*)/$ $1.html [L]

RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond /your/web/directory%1\.php -f
RewriteRule (.*)/$ $1.php [L]

RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond /your/web/directory%1\.cgi -f
RewriteRule (.*)/$ $1.cgi [L]

Sie können mir eine E-Mail an mazin (at) aztekera.com senden, wenn Sie möchten.


Ich weiß genau was ich brauche. Die Ästhetik und Funktionalität von nachgestellten Schrägstrichen in URLs ist ein Thema für sich, daher werden wir nicht darauf eingehen. Keine Sorge, dass Links unterbrochen werden, da ich gerade dabei bin, eine Website von Grund auf neu zu erstellen.

Was würden Sie dem obigen Code hinzufügen, um nachgestellte Schrägstriche am Ende von URLs zu erzwingen?

OK, ich habe das meiste hinzugefügt, was ich hatte. Ich denke immer noch, dass Sie den falschen Weg einschlagen, indem Sie nachgestellte Schrägstriche erzwingen, da dies die Pfad-Semantik bricht, aber Sie scheinen ziemlich entschlossen zu sein.

3

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:

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]

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.


1

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.


Wie ich bereits oben sagte, bin ich nicht daran interessiert, es mit PHP zu tun.

0

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.htmlund bar.php- haben und dass dies /foo/mit foo.html übereinstimmen muss und Sie wissen, dass /bar/ übereinstimmen /bar.phpmuss, kann dies getan werden. Wenn jedoch jemand hochlädt /cat.phpund jemand eintritt, /cat/weiß das System nicht, ob es übereinstimmen muss, /cat.htmloder /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.htmldann 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.htmloder /foo.phpoder /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


Ich werde keine doppelten Dateinamen haben, daher wird es niemals foo.html und foo.php geben, sodass Apache nicht entscheiden muss, welche Datei bereitgestellt werden soll.

Antwort auf Ihre Bearbeitung: Alles, was ich tun muss, ist, alle .html-, .php- und .cgi-Erweiterungen zu entfernen und dann einen nachgestellten Schrägstrich hinzuzufügen. Ich habe keinen Zweifel, dass dies getan werden kann. Ich weiß, dass dies leicht über eine PHP-Datei möglich ist, und ich weiß, dass viele Leute diese Methode bevorzugen, aber ich möchte es über .htaccess tun.

Ob es doppelte Dateinamen gibt oder nicht, ist irrelevant. Apache wird nicht wissen, welches Sie überhaupt BEDEUTEN, geschweige denn dienen. Sie benötigen ein System mit einer gewissen Intelligenz, in die Sie Ihre Regeln programmieren können, damit es weiß, welche Inhalte bereitgestellt werden sollen. Diese Option ist PHP oder ASP. Dies haben wir getan, als wir uns in einer ähnlichen Situation befanden. Wir haben JEDE Anfrage in eine einzelne .php-Datei geleitet, die dann als unser Proxy fungierte. Die PHP-Datei fragt dann jede Version der URL ab, bis sie eine gefunden hat, die keinen Status 404 zurückgibt, und liefert diesen Inhalt dann an den Browser.
Mark Henderson

Entschuldigung, habe gerade Ihren Kommentar gesehen - muss geschrieben worden sein, während ich meinen geschrieben habe. Dies kann mit .htaccess nicht durchgeführt werden - es ist einfach eine zu komplexe Aufgabe für die einfache Umschreib-Engine.
Mark Henderson

Sie sagen also, dass nur eine Dateityp-Erweiterung verarbeitet werden kann. Es kann nur .html oder nur .php sein, kann es nicht beides? Bist du dir da sicher?
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.