sorted-args: Normalisierung von HTTP-Querystring-Parametern für NGINX
Erfordert den Pro-Plan (oder höher) des GetPageSpeed NGINX Extras-Abonnements.
Installation
Sie können dieses Modul in jeder RHEL-basierten Distribution installieren, einschließlich, aber nicht beschränkt auf:
- RedHat Enterprise Linux 7, 8, 9 und 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 und Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-sorted-args
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-sorted-args
Aktivieren Sie das Modul, indem Sie Folgendes an den Anfang von /etc/nginx/nginx.conf hinzufügen:
load_module modules/ngx_http_sorted_args_module.so;
Dieses Dokument beschreibt nginx-module-sorted-args v3.0.1, veröffentlicht am 03. Mai 2026.
Ein leistungsstarkes Nginx-Modul, das HTTP-Anforderungs-Querystring-Parameter durch alphanumerische Sortierung normalisiert. Dieses Modul bietet eine konsistente, kanonische Darstellung von Query-Strings, unabhängig von der ursprünglichen Parameterreihenfolge, was es ideal für die Generierung von Cache-Schlüsseln, die Duplizierung von Anforderungen und die Normalisierung von URLs macht.
Übersicht
Verschiedene URLs mit denselben Query-Parametern in unterschiedlicher Reihenfolge erzeugen denselben normalisierten Querystring:
/index.php?b=2&a=1&c=3/index.php?b=2&c=3&a=1/index.php?c=3&a=1&b=2/index.php?c=3&b=2&a=1
Alle oben genannten erzeugen denselben normalisierten Querystring: a=1&b=2&c=3
Diese Normalisierung ist über die Variable $sorted_args zugänglich, die in Cache-Schlüsseln, Protokollierung und anderen NGINX-Kontexten verwendet werden kann.
Funktionen
- ✅ Natürliche Sortierung der Query-Parameter nach Schlüssel, dann nach Wert (z.B.
item2<item10) - ✅ Entfernen leerer Werte — Parameter wie
?a=werden automatisch entfernt - ✅ Blocklistenmodus (
sorted_args_ignore_list), um bestimmte Parameter aus der sortierten Ausgabe auszuschließen - ✅ Whitelistmodus (
sorted_args_allow_list), um nur bestimmte Parameter beizubehalten und alle anderen zu verwerfen - ✅ Wildcard-Muster — verwenden Sie
utm_*, um alle UTM-Parameter zu erfassen,*_idfür Suffixe - ✅ Duplikatserkennung (
sorted_args_dedupe) — nur die erste oder letzte Vorkommen von doppelten Schlüsseln beibehalten - ✅ Optionale
$args-Überschreibung, um den ursprünglichen Querystring automatisch durch sortierte Argumente zu ersetzen - ✅ Standortbezogene Konfiguration mit Vererbung aus Server- und Hauptkontexten
- ✅ Effiziente Implementierung unter Verwendung der nativen Warteschlangen-Sortierung von NGINX
- ✅ Groß-/Kleinschreibung ignorierende Parameterbenennung für Filterung
- ✅ Duplikaterkennung in Filterlisten
Konfiguration
Variablen
$sorted_args
Gibt die Querystring-Parameter zurück, die alphanumerisch nach Parametername und dann nach Wert sortiert sind. Parameter werden mit & verbunden und behalten ihre ursprüngliche URL-Codierung.
Beispiel:
Anfrage: /page?zebra=1&apple=2&banana=3
$sorted_args: apple=2&banana=3&zebra=1
Verhalten:
- Ein leerer Querystring gibt einen leeren String zurück
- Parameter ohne Werte (z.B. ?param) werden als param einbezogen
- Parameter mit leeren Werten (z.B. ?param=) werden automatisch entfernt
- Mehrere Werte für denselben Parameter werden einzeln sortiert
- Natürliche Sortierung: p=1, p=2, p=10 sortieren korrekt (nicht p=1, p=10, p=2)
- Groß-/Kleinschreibung ignorierende Sortierung für Parameternamen
Direktiven
sorted_args_ignore_list
Syntax: sorted_args_ignore_list pattern [pattern ...];
Standard: keine
Kontext: http, server, location, if
Beschreibung:
Gibt ein oder mehrere Muster an, die aus der Variable $sorted_args ausgeschlossen werden sollen (Blocklistenmodus). Dies ist nützlich, um Cache-busting-Parameter (wie Zeitstempel, Versionsnummern oder Tracking-IDs) aus Cache-Schlüsseln zu entfernen, während andere Parameter beibehalten werden.
Musterarten:
- name — exakte Übereinstimmung (groß-/kleinschreibung ignorierend)
- name* — Präfixübereinstimmung (übereinstimmt mit name, name_foo, name123 usw.)
- *name — Suffixübereinstimmung (übereinstimmt mit foo_name, bar_name usw.)
- *name* — Enthält-Übereinstimmung (übereinstimmt mit jedem Parameter, der name enthält)
Doppelte Muster in der Liste werden automatisch entfernt.
Beispiel:
location /api {
# Exakte Namen und alle utm_* Tracking-Parameter filtern
sorted_args_ignore_list timestamp version _ utm_* fb_*;
proxy_cache_key "$uri$sorted_args";
proxy_pass http://backend;
}
In diesem Beispiel erzeugen Anfragen wie /api?user=123×tamp=1234567890&utm_source=google&utm_medium=cpc $sorted_args als user=123, wobei timestamp und alle UTM-Parameter herausgefiltert werden.
sorted_args_allow_list
Syntax: sorted_args_allow_list pattern [pattern ...];
Standard: keine
Kontext: http, server, location, if
Beschreibung:
Gibt ein oder mehrere Muster an, die in der Variable $sorted_args behalten werden sollen (Whitelistmodus). Alle Parameter, die keinem Muster entsprechen, werden ausgeschlossen. Dies ist nützlich, wenn Sie genau steuern möchten, welche Query-Parameter für das Caching zulässig sind.
Musterarten:
- name — exakte Übereinstimmung (groß-/kleinschreibung ignorierend)
- name* — Präfixübereinstimmung (übereinstimmt mit name, name_foo, name123 usw.)
- *name — Suffixübereinstimmung (übereinstimmt mit foo_name, bar_name usw.)
- *name* — Enthält-Übereinstimmung (übereinstimmt mit jedem Parameter, der name enthält)
Wenn sowohl sorted_args_allow_list als auch sorted_args_ignore_list konfiguriert sind, wird die Whitelist zuerst angewendet (nur erlaubte Parameter werden beibehalten), dann wird die Ignorierliste angewendet, um verbleibende unerwünschte Parameter herauszufiltern.
Beispiel:
location /api {
# Nur Paginierungs- und Sortierungsparameter zulassen
sorted_args_allow_list page* sort* limit;
proxy_cache_key "$uri$sorted_args";
proxy_pass http://backend;
}
In diesem Beispiel wird eine Anfrage wie /api?page=1&page_size=10&sort=asc×tamp=123 $sorted_args als limit=10&page=1&page_size=10&sort=asc erzeugen. Der timestamp-Parameter wird verworfen, da er keinem Muster entspricht.
sorted_args_overwrite
Syntax: sorted_args_overwrite on | off;
Standard: off
Kontext: http, server, location, if
Beschreibung:
Wenn aktiviert, überschreibt diese Direktive automatisch die eingebaute Variable $args mit den sortierten (und optional gefilterten) Query-Argumenten. Dies ist nützlich, wenn Sie möchten, dass alle nachgelagerten Prozesse (Proxying, Protokollierung, Weiterleitungen) den normalisierten Querystring verwenden, ohne explizit auf $sorted_args zu verweisen.
Die Überschreibung erfolgt während der Rewrite-Phase, sodass alle nachfolgenden Phasen die sortierten Argumente in $args sehen.
Beispiel:
location /api {
sorted_args_overwrite on;
sorted_args_ignore_list timestamp version;
# $args ist jetzt automatisch sortiert und gefiltert
proxy_pass http://backend$uri?$args;
}
In diesem Beispiel wird eine Anfrage an /api?z=1&a=2×tamp=123 als /api?a=2&z=1 proxied — sortiert und mit timestamp herausgefiltert.
sorted_args_dedupe
Syntax: sorted_args_dedupe first | last | off;
Standard: off
Kontext: http, server, location, if
Beschreibung:
Steuert, wie doppelte Parameter-Schlüssel behandelt werden. Wenn mehrere Parameter denselben Schlüssel haben (z.B. ?a=1&a=2&a=3), bestimmt diese Direktive, welchen Wert man beibehalten möchte.
first— nur das erste Vorkommen jedes Schlüssels beibehaltenlast— nur das letzte Vorkommen jedes Schlüssels beibehaltenoff— alle Vorkommen beibehalten (Standardverhalten)
Dies ist nützlich, um URLs zu normalisieren, bei denen derselbe Parameter möglicherweise mehrfach angegeben wird, um konsistente Cache-Schlüssel sicherzustellen.
Beispiel:
location /search {
sorted_args_dedupe first;
proxy_cache_key "$uri$sorted_args";
proxy_pass http://backend;
}
In diesem Beispiel wird eine Anfrage wie /search?q=foo&q=bar&q=baz $sorted_args als q=foo erzeugen, wobei nur der erste Wert beibehalten wird. Mit sorted_args_dedupe last würde es q=baz erzeugen.
Anwendungsbeispiele
Grundlegende Cache-Schlüssel-Normalisierung
Normalisieren Sie Cache-Schlüssel unabhängig von der Parameterreihenfolge:
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m;
server {
listen 80;
location / {
proxy_cache my_cache;
proxy_cache_key "$scheme$host$uri$sorted_args";
proxy_pass http://backend;
}
}
}
Automatische Argumentüberschreibung
Automatisch $args mit sortierten Parametern für alle nachgelagerten Prozesse umschreiben:
server {
listen 80;
location /api {
sorted_args_overwrite on;
sorted_args_ignore_list timestamp _;
# Alle diese verwenden jetzt automatisch sortierte, gefilterte Argumente
proxy_pass http://backend;
# Entspricht: proxy_pass http://backend$uri?$sorted_args;
}
}
Herausfiltern von Cache-Busting-Parametern
Entfernen Sie Zeitstempel- und Tracking-Parameter aus Cache-Schlüsseln:
location /static {
sorted_args_ignore_list _ t timestamp v version;
proxy_cache zone;
proxy_cache_key "$uri$sorted_args";
proxy_pass http://cdn;
}
Whitelistmodus (Nur bestimmte Parameter zulassen)
Wenn Query-Parameter zu schwerem serverseitigem Processing führen können, verwenden Sie eine Whitelist, um streng zu steuern, welche Parameter für das Caching zulässig sind:
location /search {
# Nur diese Parameter beeinflussen den Cache-Schlüssel; alle anderen werden verworfen
sorted_args_allow_list q page limit category;
proxy_cache zone;
proxy_cache_key "$uri$sorted_args";
proxy_pass http://search_backend;
}
In diesem Beispiel werden Anfragen wie /search?q=nginx&page=1&debug=true&nocache=1 unter Verwendung von nur category=&limit=&page=1&q=nginx zwischengespeichert, wodurch effektiv alle Cache-busting- oder Debugging-Parameter ignoriert werden.
Kombination von Whitelist und Blockliste
Sie können beide Direktiven zusammen verwenden, um eine feinkörnige Kontrolle zu erhalten. Die Whitelist wird zuerst angewendet, dann die Blockliste:
location /api {
# Zuerst nur diese Parameter beibehalten
sorted_args_allow_list user_id action page limit timestamp;
# Dann den Zeitstempel aus dem erlaubten Set entfernen
sorted_args_ignore_list timestamp;
proxy_cache zone;
proxy_cache_key "$uri$sorted_args";
proxy_pass http://api_backend;
}
Protokollierung normalisierter Querystrings
Fügen Sie sortierte Querystrings in den Zugriffsprotokollen ein:
http {
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'args="$args" sorted_args="$sorted_args"';
server {
access_log /var/log/nginx/access.log detailed;
# ...
}
}
Standortbezogene Filterung
Verschiedene Standorte können unterschiedliche Filterlisten haben:
server {
# Standard: Filtert gängige Tracking-Parameter
sorted_args_ignore_list _ utm_source utm_medium utm_campaign;
location /api {
# API: auch Version und Zeitstempel filtern
sorted_args_ignore_list _ utm_source utm_medium utm_campaign version t;
proxy_pass http://api_backend;
}
location /content {
# Inhalt: nur Tracking filtern
proxy_pass http://content_backend;
}
}
Vollständiges Beispiel
pid logs/nginx.pid;
error_log logs/error.log warn;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent" '
'args="$args" sorted_args="$sorted_args"';
access_log logs/access.log main;
proxy_cache_path /tmp/cache
levels=1:2
keys_zone=zone:10m
inactive=10d
max_size=100m;
server {
listen 8080;
server_name localhost;
# Filtert Tracking- und Cache-Busting-Parameter
location /filtered {
sorted_args_ignore_list v _ time timestamp;
proxy_set_header Host "backend";
proxy_pass http://localhost:8081;
proxy_cache zone;
proxy_cache_key "$uri$sorted_args";
proxy_cache_valid 200 1m;
}
# Verwenden Sie sortierte Argumente ohne Filterung
location / {
proxy_pass http://localhost:8081;
proxy_cache zone;
proxy_cache_key "$uri$sorted_args";
proxy_cache_valid 200 10m;
}
}
# Backend-Server zum Testen
server {
listen 8081;
location / {
return 200 "args: $args\nsorted_args: $sorted_args\n";
}
}
}
Wie es funktioniert
- Parameterextraktion: Das Modul analysiert den Querystring aus
r->args, indem es an&und=splittet. - Warteschlangenaufbau: Jeder Parameter wird in einer Warteschlangenstruktur mit seinem Schlüssel, Wert und vollständigem Schlüssel-Wert-Paar gespeichert.
- Sortierung: Parameter werden mit einer natürlichen Vergleichsfunktion sortiert:
- Primäre Sortierung: Parametername (groß-/kleinschreibung ignorierend, natürliche Reihenfolge)
- Sekundäre Sortierung: vollständiger Parameterstring (key=value, natürliche Reihenfolge)
- Natürliche Reihenfolge bedeutet, dass eingebettete Zahlen numerisch verglichen werden:
item2<item10 - Entfernen leerer Werte: Parameter mit
=aber ohne Wert (wie?a=) werden entfernt. - Whitelist-Filterung: Wenn
sorted_args_allow_listkonfiguriert ist, werden nur Parameter, die den Mustern entsprechen, beibehalten. - Blocklisten-Filterung: Parameter, die den Mustern in
sorted_args_ignore_listentsprechen, werden ausgeschlossen. - Duplikaterkennung: Wenn
sorted_args_dedupeaktiviert ist, wird nur das erste oder letzte Vorkommen jedes Schlüssels beibehalten. - Rekonstruktion: Die sortierten, gefilterten Parameter werden mit
&verbunden, um den finalen String zu bilden.
Testen
Dieses Projekt verwendet Test::Nginx für seine Test-Suite, die in Docker für reproduzierbare Builds ausgeführt wird.
Voraussetzungen
- Docker
Tests ausführen
Führen Sie die gesamte Test-Suite aus:
make tests
Führen Sie eine bestimmte Testdatei aus:
make tests T=t/sorted_args.t
Deaktivieren Sie den HUP-Modus zur Fehlersuche (langsamer, aber isolierter):
make tests HUP=0
Verwenden Sie eine andere NGINX-Version:
make tests NGINX_VERSION=release-1.26.2
Öffnen Sie eine interaktive Shell im Testcontainer zur Fehlersuche:
make shell
Testabdeckung
Die Test-Suite überprüft:
- ✅ Grundlegende Sortierfunktionalität
- ✅ Natürliche/numerische Sortierung (z.B. p=1, p=2, p=10 in der richtigen Reihenfolge)
- ✅ Array-ähnliche Parameter (z.B. c[]=1&c[]=2)
- ✅ Blocklistenfilterung (sorted_args_ignore_list)
- ✅ Whitelistfilterung (sorted_args_allow_list)
- ✅ Kombinierte Verwendung von Whitelist und Blockliste
- ✅ Wildcard-Muster: Präfix (utm_*), Suffix (*_id), enthält (*token*)
- ✅ Duplikaterkennung: sorted_args_dedupe first und last
- ✅ Umgang mit leerem Querystring
- ✅ Entfernen leerer Werte (?a=&b=2 → b=2)
- ✅ Verwendung von Cache-Schlüsseln
- ✅ Standortbezogene Konfigurationsvererbung
- ✅ Direktive sorted_args_overwrite
- ✅ Groß-/Kleinschreibung ignorierende Parameterübereinstimmung (sowohl Whitelist als auch Blockliste)
- ✅ Parameter ohne Werte vs. leere Werte
- ✅ Umgang mit doppelten Parametern
- ✅ Erhaltung spezieller Zeichen
- ✅ Fehlerhafte Query-Strings (aufeinanderfolgende kaufmännische Und-Zeichen)
- ✅ Parameter mit mehreren Gleichheitszeichen
- ✅ E2E: $args wird vor der Auswertung des Cache-Schlüssels geändert (REWRITE-Phasenzeitpunkt)
- ✅ E2E: Umgestellte Parameter erzeugen identische Cache-Schlüssel
- ✅ E2E: Rewrite-Direktiven sehen überschriebenes $args
Leistungsüberlegungen
- Der sortierte Querystring wird einmal pro Anfrage berechnet und im Anfragekontext zwischengespeichert.
- Die Sortierung verwendet den effizienten warteschlangenbasierten Algorithmus von NGINX.
- Die Filterung verwendet eine groß-/kleinschreibung ignorierende Zeichenfolgenvergleich.
- Die Speicherzuweisung erfolgt aus dem Anfragepool, sodass keine explizite Bereinigung erforderlich ist.
Einschränkungen
- Parameterwerte werden nicht decodiert/codiert; die ursprüngliche Codierung bleibt erhalten.
- Die Filterung ist für Parameternamen groß-/kleinschreibung ignorierend, bewahrt jedoch die ursprüngliche Groß-/Kleinschreibung in der Ausgabe.
- Parameter mit leeren Werten (z.B.
?a=) werden immer entfernt; verwenden Sie?a(ohne Gleichheitszeichen) für Flags.