Wie ordne ich URL-Parameter / Abfragezeichenfolgen mit Apache htaccess neu an?

Sep 18 2020

Ich habe E-Commerce-Kategorien mit facettierter Navigation (Filterung). Durch das Filtern können Tausende von (nützlichen) URLs generiert werden. Ich möchte nr reduzieren. von möglichen URLs, indem bestimmte Inhalte immer auf derselben URL mit derselben Abfragezeichenfolgenparameterreihenfolge angezeigt werden.

Aus SEO-Sicht könnte ich das kanonische Tag verwenden, um doppelte URLs logisch zu entfernen, aber aus Sicht der Leistung wäre es viel besser, es mit RewriteRules zu lösen.

Beispiel-URLs mit demselben Inhalt, aber unterschiedlicher Parameterreihenfolge:

  • https://example.com/category/subcategory/?filter_manuf=grohe&filter_style=design&filter_family=bauedge&filter_warranty=5y
  • https://example.com/category/subcategory/?filter_style=design&filter_manuf=grohe&filter_warranty=5y&filter_family=bauedge

Diese URLs sollten zu einer URL umgeleitet werden, in der Abfrageparameter immer in derselben Reihenfolge angezeigt werden. z.B:

https://example.com/category/subcategory/?filter_manuf=grohe&filter_family=bauedge&filter_style=design&filter_warranty=5y

Beachten Sie, dass:

  • Ich habe mehr als 10 Filterkriterien (Abfrageparameter)
  • Die Reihenfolge der Parameter ändert sich entsprechend der Filterauswahlreihenfolge des Benutzers. Sie können in beliebiger Reihenfolge angezeigt werden.
  • In der URL werden nur die verwendeten Parameter angezeigt. Einige Seiten haben einen oder zwei Parameter in ihrer URL, andere bis zu zehn oder mehr.

Haben Sie eine Idee, wie dies erreicht werden kann?

Ich habe in dieser Frage etwas Vielversprechendes gefunden, aber ich kann es nicht zum Laufen bringen :
RewriteCond, um Abfragezeichenfolgenparameter in beliebiger Reihenfolge abzugleichen

Antworten

MrWhite Sep 24 2020 at 00:13

Aus Sicht der Leistung wäre es jedoch viel besser, es mit RewriteRules zu lösen.

Unter Leistungsgesichtspunkten ist es weitaus besser, dies in Ihrer Anwendung zu beheben, nicht in .htaccess/ mod_rewrite (dh RewriteRules). Sie möchten immer korrekt auf die kanonische URL verlinken.

Sie möchten den Benutzer auf keinen Fall extern umleiten, da er Filter anwendet, um die Reihenfolge der URL-Parameter zu "korrigieren". Die URL-Parameter sollten von Ihrer Anwendung zunächst "richtig" angewendet werden.

Das "Weiterleiten" des Benutzers ist nur dann von Vorteil, wenn er einem nicht-kanonischen Link eines Drittanbieters (von einer anderen Website oder Suchmaschine) gefolgt ist und Sie potenzielle SEO-Probleme lösen müssen. Aber selbst dann sollte der Code zum Korrigieren der URL-Parameterreihenfolge viel einfacher (und leichter zu pflegen) sein, wenn er als Teil Ihrer Anwendungslogik implementiert wird, nicht .htaccess. Der Code dafür .htaccessist vergleichsweise "komplexer" (sprich: chaotisch, möglicherweise schwieriger zu warten, fehleranfälliger usw.)

Es ist jedoch ein interessantes Problem, und es kann vorkommen, dass es vorzuziehen (oder erforderlich) ist, dies in .htaccess(oder in der Apache-Serverkonfiguration ) zu codieren, wenn Sie dies in Ihrer Anwendung nicht einfach tun können.

Lösung mit mod_rewrite in .htaccess(oder Serverkonfiguration)

(Beachten Sie jedoch die obigen Kommentare - dies ist möglicherweise nicht das, was Sie tun sollten.)

Dies ist eine einigermaßen generische Lösung, die in .htaccess(oder in der Serverkonfiguration) funktioniert . So wie es aussieht, funktioniert es auf jedem URL-Pfad. Damit es auf einem einzelnen URL-Pfad funktioniert (z. B. /category/subcategory/wie in der Frage angegeben), ändern Sie das Muster in der endgültigen RewriteRuleAnweisung. Zum Beispiel:

RewriteRule ^category/subcategory/$ %{REQUEST_URI}?%{ENV:NEW_QUERY_STRING} [NE,R=302,L]

Sie können auch oben eine Ausnahme schreiben, um diese Regeln für bestimmte URLs zu überspringen, wenn Sie sie auf eine Gruppe von URLs und nicht auf andere anwenden müssen. Dies ist möglicherweise optimaler, da keine unnötige Verarbeitung der Abfragezeichenfolge erforderlich ist.

Dieser Codeblock muss sich am Anfang Ihrer .htaccessDatei befinden. (Ordnung ist wichtig.)

Dieser Code hat den zusätzlichen "Vorteil", dass er auch die Abfragezeichenfolge "bereinigt", indem alle nicht definierten URL-Parameter entfernt werden (oben im Skript).

Da es nicht trivial ist, "einfach" festzustellen, ob die ursprünglichen URL-Parameter bereits in der richtigen Reihenfolge vorliegen, erstellt das Skript eine neue Abfragezeichenfolge mit den URL-Parametern in der richtigen Reihenfolge und vergleicht diese mit der ursprünglichen Abfrage Zeichenfolge, um festzustellen, ob eine Umleitung erforderlich ist.

Kriterien:

  • Bis zu 10 URL-Parameter
  • Es können beliebig viele URL-Parameter in beliebiger Reihenfolge angezeigt werden
  • Leere URL-Parameter sollten nicht enthalten sein
  • Bei URL-Parametern wird zwischen Groß- und Kleinschreibung unterschieden
  • Funktioniert für jeden URL-Pfad
  • URL Parameternamen entsprechen den regulären Ausdruck [\w-]+(dh. a-z, A-Z, 0-9, _Und -)
  • URL-Parameterwerte dürfen nicht enthalten @(es sei denn, die URL ist codiert).
  • @@@ kann nirgendwo in der Abfragezeichenfolge erscheinen

Sie müssen lediglich die URL-Parameternamen oben im Skript in der gewünschten Reihenfolge definieren. Diese werden in Umgebungsvariablen gehalten VAR_NAME_01, VAR_NAME_02usw. Der Rest des Skripts soll unverändert arbeiten , es sei denn:

  • Sie müssen weitere URL-Parameter hinzufügen
  • ODER ändern Sie das intern verwendete Zeichen, um Abschnitte im Mustervergleich abzugrenzen (derzeit " @").
  • ODER beschränken Sie den Code auf einen bestimmten URL-Pfad.

Skript:

# Define the "name" of each URL parameter
# The numeric order determines the order of the resulting URL parameter list.
# Comment out any URL parameters that are not required.
SetEnvIf ^ ^ VAR_NAME_01=one
SetEnvIf ^ ^ VAR_NAME_02=two
SetEnvIf ^ ^ VAR_NAME_03=three
SetEnvIf ^ ^ VAR_NAME_04=four
SetEnvIf ^ ^ VAR_NAME_05=five
SetEnvIf ^ ^ VAR_NAME_06=six
SetEnvIf ^ ^ VAR_NAME_07=seven
SetEnvIf ^ ^ VAR_NAME_08=eight
SetEnvIf ^ ^ VAR_NAME_09=nine
SetEnvIf ^ ^ VAR_NAME_10=ten

###############################################################################
# Shouldn't need to modify directives below here...

RewriteEngine on
Options +FollowSymLinks

# -----------------------------------------------------------------------------
# Read each URL parameter (if any) and store in corresponding env var

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_01} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_01:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_02} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_02:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_03} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_03:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_04} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_04:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_05} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_05:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_06} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_06:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_07} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_07:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_08} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_08:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_09} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_09:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_10} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_10:%2]

# -----------------------------------------------------------------------------
# Construct new query string
# Only with URL parameters that are not empty

RewriteCond %{ENV:VAR_VALUE_01} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:VAR_NAME_01}=%{ENV:VAR_VALUE_01}]

RewriteCond %{ENV:VAR_VALUE_02} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_02}=%{ENV:VAR_VALUE_02}]

RewriteCond %{ENV:VAR_VALUE_03} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_03}=%{ENV:VAR_VALUE_03}]

RewriteCond %{ENV:VAR_VALUE_04} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_04}=%{ENV:VAR_VALUE_04}]

RewriteCond %{ENV:VAR_VALUE_05} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_05}=%{ENV:VAR_VALUE_05}]

RewriteCond %{ENV:VAR_VALUE_06} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_06}=%{ENV:VAR_VALUE_06}]

RewriteCond %{ENV:VAR_VALUE_07} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_07}=%{ENV:VAR_VALUE_07}]

RewriteCond %{ENV:VAR_VALUE_08} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_08}=%{ENV:VAR_VALUE_08}]

RewriteCond %{ENV:VAR_VALUE_09} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_09}=%{ENV:VAR_VALUE_09}]

RewriteCond %{ENV:VAR_VALUE_10} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_10}=%{ENV:VAR_VALUE_10}]

# -----------------------------------------------------------------------------
# Trim "&" prefix from the NEW_QUERY_STRING
RewriteCond %{ENV:NEW_QUERY_STRING} ^&(.+)
RewriteRule ^ - [E=NEW_QUERY_STRING:%1]

# Compare with existing QUERY_STRING to determine whether it's in the correct order already
# If different then redirect...
RewriteCond %{QUERY_STRING}@@@%{ENV:NEW_QUERY_STRING} !^(.+)@@@\1
RewriteRule ^ %{REQUEST_URI}?%{ENV:NEW_QUERY_STRING} [NE,R=302,L]

Wenn Sie Fragen zu bestimmten Teilen dieses Skripts haben, sagen Sie einfach in den Kommentaren ...