Come posso avere la stessa regola per due posizioni nella configurazione di NGINX?


153

Come posso avere la stessa regola per due posizioni nella configurazione di NGINX?

Ho provato quanto segue

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

ma nginx reload ha generato questo errore:

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

Risposte:


240

Provare

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

I ~mezzi per usare un'espressione regolare per l'URL. I ^mezzi per controllare dal primo carattere. Questo cercherà un /seguito da una delle posizioni e poi un'altra /.


37
NOTA: se ciò si verifica spesso (come migliaia), si verificherà una penalità prestazionale a causa della corrispondenza regex. Anche l'ordine di abbinamento è sostanzialmente diverso. In molti casi "piccoli", si comporterà come vuoi tu, ma è qualcosa di cui devi essere consapevole. Personalmente desidero che Nginx "location" supporti più condizioni "=" invece di fare affidamento su una regola regex.
Bernard,

7
IMHO, questo dovrebbe essere più efficiente: location ~ (patternOne | patternTwo) {...}
stamster

2
Questa soluzione non ha funzionato per me; comunque il commento di @ stamster ha fatto; Sto correndonginx/1.13.2
TJ Biddle il

1
se avete bisogno proxy_passdi lavorare, vedere questa risposta: stackoverflow.com/a/46625656/1246870
avs099

1
Questo non funziona per me quando l'URL originale termina senza barra
Il padrino

88

Un'altra opzione è quella di ripetere le regole in due posizioni di prefisso usando un file incluso. Poiché le posizioni dei prefissi sono indipendenti dalla posizione nella configurazione, il loro utilizzo può salvare un po 'di confusione quando si aggiungono altre posizioni di regex in un secondo momento. Evitare le posizioni di regex quando puoi aiuterà a ridimensionare la tua configurazione senza problemi.

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

Ecco un esempio 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
";

puoi aggiungere per favore shared.confesempio e posizione?
Дмитрий Кулешов

5
Ho aggiunto un esempio di file shared.conf. È possibile utilizzare un percorso assoluto per shared.conf o inserirlo nella directory nginx. In questo caso, contiene solo un paio di direttive.
Cole Tierney,

40

Sia i file regex che quelli inclusi sono buoni metodi e li uso spesso. Ma un'altra alternativa è quella di utilizzare una "posizione denominata", che è un approccio utile in molte situazioni, specialmente quelle più complicate. La pagina ufficiale "If is Evil" mostra essenzialmente quanto segue come un buon modo per fare le cose:

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

Ci sono vantaggi e svantaggi in questi vari approcci. Un grande vantaggio di una regex è che puoi catturare parti della partita e usarle per modificare la risposta. Naturalmente, di solito è possibile ottenere risultati simili con gli altri approcci impostando una variabile nel blocco originale o usando map. Il rovescio della medaglia dell'approccio regex è che può diventare ingombrante se si desidera abbinare una varietà di posizioni, inoltre la bassa precedenza di una regex potrebbe non adattarsi a come si desidera abbinare le posizioni - per non parlare del fatto che ci sono apparentemente impatti sulle prestazioni dalle regex in alcuni casi.

Il vantaggio principale di includere i file (per quanto ne so) è che è un po 'più flessibile riguardo esattamente ciò che è possibile includere, ad esempio non deve essere un blocco di posizione completo. Ma è anche soggettivamente un po 'più clunkier delle posizioni nominate.

Si noti inoltre che esiste una soluzione correlata che è possibile utilizzare in situazioni simili: posizioni nidificate. L'idea è di iniziare con una posizione molto generale, applicare una configurazione comune a molte delle possibili corrispondenze e quindi disporre di posizioni nidificate separate per i diversi tipi di percorsi che si desidera abbinare. Ad esempio, potrebbe essere utile fare qualcosa del genere:

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

7

Questo è un approccio breve, ma efficace e comprovato:

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

Quindi si possono facilmente avere più pattern con una semplice sintassi di pipe che punta allo stesso blocco / regole di posizione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.