Wie kann ich dieselbe Regel für zwei Standorte in der NGINX-Konfiguration haben?

153

Wie kann ich dieselbe Regel für zwei Standorte in der NGINX-Konfiguration haben?

Ich habe folgendes versucht

server {
  location /first/location/ | /second/location/ {
  ..
  ..
  }
}

aber nginx reload warf diesen Fehler:

nginx: [emerg] invalid number of arguments in "location" directive**
user1661010
quelle

Antworten:

238

Versuchen

location ~ ^/(first/location|second/location)/ {
  ...
}

Die ~Möglichkeit, einen regulären Ausdruck für die URL zu verwenden. Die ^Mittel, um vom ersten Zeichen zu überprüfen. Dies sucht nach einem /gefolgt von einem der Standorte und dann nach einem anderen /.

Curtwphillips
quelle
37
HINWEIS: Wenn dies häufig vorkommt (z. B. bei Tausenden), führt dies zu einer Leistungsminderung aufgrund des Regex-Abgleichs. Auch die Reihenfolge der Übereinstimmung ist wesentlich unterschiedlich. In vielen "kleinen" Fällen verhält es sich so, wie Sie es möchten, aber dies ist etwas, das Sie beachten sollten. Ich persönlich möchte, dass der "Standort" von Nginx mehrere "=" - Bedingungen unterstützt, anstatt sich auf eine Regex-Regel zu verlassen.
Bernard
7
IMHO sollte dies effizienter sein: location ~ (patternOne | patternTwo) {...}
stamster
2
Diese Lösung hat bei mir nicht funktioniert; jedoch tat @ stamsters Kommentar; Ich rennenginx/1.13.2
TJ Biddle
1
Wenn Sie arbeiten müssen proxy_pass, lesen
avs099
1
Dies funktioniert nicht für mich, wenn die ursprüngliche URL ohne Schrägstrich endet
The Godfather
88

Eine andere Möglichkeit besteht darin, die Regeln an zwei Präfixpositionen mithilfe einer enthaltenen Datei zu wiederholen. Da Präfixpositionen in der Konfiguration positionsunabhängig sind, kann ihre Verwendung Verwirrung stiften, wenn Sie später andere Regex-Positionen hinzufügen. Wenn Sie Regex-Positionen vermeiden, wenn dies möglich ist, kann Ihre Konfiguration reibungslos skaliert werden.

server {
    location /first/location/ {
        include shared.conf;
    }
    location /second/location/ {
        include shared.conf;
    }
}

Hier ist ein Beispiel shared.conf:

default_type text/plain;
return 200 "http_user_agent:    $http_user_agent
remote_addr:    $remote_addr
remote_port:    $remote_port
scheme:     $scheme
nginx_version:  $nginx_version
";
Cole Tierney
quelle
Kannst du bitte shared.confBeispiel und Ort hinzufügen ?
Дмитрий Кулешов
5
Ich habe eine Beispieldatei shared.conf hinzugefügt. Sie können einen absoluten Pfad zur shared.conf verwenden oder ihn in Ihrem nginx-Verzeichnis ablegen. In diesem Fall enthält es nur ein paar Anweisungen.
Cole Tierney
39

Sowohl der Regex als auch die enthaltenen Dateien sind gute Methoden, und ich verwende diese häufig. Eine andere Alternative ist die Verwendung eines "benannten Ortes", was in vielen Situationen - insbesondere in komplizierteren - ein nützlicher Ansatz ist. Die offizielle Seite "If is Evil" zeigt im Wesentlichen Folgendes als eine gute Möglichkeit, Dinge zu tun:

error_page 418 = @common_location;
location /first/location/ {
    return 418;
}
location /second/location/ {
    return 418;
}
location @common_location {
    # The common configuration...
}

Diese verschiedenen Ansätze haben Vor- und Nachteile. Ein großer Vorteil eines regulären Ausdrucks besteht darin, dass Sie Teile des Spiels erfassen und zum Ändern der Antwort verwenden können. Natürlich können Sie mit den anderen Ansätzen normalerweise ähnliche Ergebnisse erzielen, indem Sie entweder eine Variable im ursprünglichen Block festlegen oder verwenden map. Der Nachteil des Regex-Ansatzes besteht darin, dass er unhandlich werden kann, wenn Sie eine Vielzahl von Standorten abgleichen möchten. Außerdem passt die niedrige Priorität eines Regex möglicherweise nicht dazu, wie Sie Standorte abgleichen möchten - ganz zu schweigen davon, dass es anscheinend Auswirkungen auf die Leistung gibt in einigen Fällen von regulären Ausdrücken.

Der Hauptvorteil des Einfügens von Dateien (soweit ich das beurteilen kann) besteht darin, dass es etwas flexibler ist, was genau Sie einschließen können - es muss beispielsweise kein vollständiger Speicherortblock sein. Aber es ist auch subjektiv etwas klobiger als die genannten Orte.

Beachten Sie auch, dass es eine verwandte Lösung gibt, die Sie möglicherweise in ähnlichen Situationen verwenden können: verschachtelte Speicherorte. Die Idee ist, dass Sie mit einem sehr allgemeinen Speicherort beginnen, eine Konfiguration anwenden, die mehreren der möglichen Übereinstimmungen gemeinsam ist, und dann separate verschachtelte Speicherorte für die verschiedenen Arten von Pfaden haben, die Sie abgleichen möchten. Zum Beispiel könnte es nützlich sein, so etwas zu tun:

location /specialpages/ {
    # some config
    location /specialpages/static/ {
        try_files $uri $uri/ =404;
    }
    location /specialpages/dynamic/ {
        proxy_pass http://127.0.0.1;
    }
}
Mike
quelle
7

Dies ist ein kurzer, aber effizienter und bewährter Ansatz:

location ~ (patternOne|patternTwo){ #rules etc. }

So kann man leicht mehrere Muster mit einfacher Pipe-Syntax haben, die auf denselben Standortblock / dieselben Regeln verweisen.

Stamster
quelle