¿Cómo puedo tener la misma regla para dos ubicaciones en la configuración de NGINX?

153

¿Cómo puedo tener la misma regla para dos ubicaciones en la configuración de NGINX?

He probado lo siguiente

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

pero nginx reload arrojó este error:

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

Respuestas:

239

Tratar

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

Los ~medios para usar una expresión regular para la url. Los ^medios para verificar desde el primer personaje. Esto buscará un /seguido por cualquiera de las ubicaciones y luego otro /.

Curtwphillips
fuente
37
NOTA: si esto ocurre con frecuencia (como miles), incurrirá en una penalización de rendimiento debido a la coincidencia de expresiones regulares. Además, el orden de coincidencia es sustancialmente diferente. En muchos casos "pequeños", se comportará como usted desea, pero esto es algo de lo que debe estar atento. Personalmente, quiero que la "ubicación" de Nginx admita múltiples "=" condiciones en lugar de depender de una regla de expresiones regulares.
Bernard
77
En mi humilde opinión, esto debería ser más eficiente: ubicación ~ (patternOne | patternTwo) {...}
stamster
2
Esta solución no funcionó para mí; Sin embargo, el comentario de @ stamster sí; Estoy corriendonginx/1.13.2
TJ Biddle
1
si necesita proxy_passtrabajar, vea esta respuesta: stackoverflow.com/a/46625656/1246870
avs099
1
Esto no funciona para mí cuando la URL original termina sin barra
The Godfather
88

Otra opción es repetir las reglas en dos ubicaciones de prefijos utilizando un archivo incluido. Dado que las ubicaciones de los prefijos son independientes de la posición en la configuración, su uso puede ahorrar cierta confusión al agregar otras ubicaciones de expresiones regulares más adelante. Evitar las ubicaciones de expresiones regulares cuando pueda ayudará a que su configuración escale sin problemas.

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

Aquí hay una muestra de 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
fuente
¿puedes agregar por favor shared.confejemplo y ubicación?
Дмитрий Кулешов
55
He agregado un ejemplo de archivo shared.conf. Puede usar una ruta absoluta al shared.conf o ponerla en su directorio nginx. En este caso, solo contiene un par de directivas.
Cole Tierney el
40

Tanto la expresión regular como los archivos incluidos son buenos métodos, y los uso con frecuencia. Pero otra alternativa es utilizar una "ubicación con nombre", que es un enfoque útil en muchas situaciones, especialmente en las más complicadas. La página oficial "If is Evil" muestra esencialmente lo siguiente como una buena manera de hacer las cosas:

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

Hay ventajas y desventajas de estos diversos enfoques. Una gran ventaja de una expresión regular es que puedes capturar partes de la partida y usarlas para modificar la respuesta. Por supuesto, generalmente puede lograr resultados similares con los otros enfoques configurando una variable en el bloque original o utilizando map. La desventaja del enfoque de expresiones regulares es que puede volverse difícil de manejar si desea hacer coincidir una variedad de ubicaciones, además la baja precedencia de una expresión regular podría no coincidir con la forma en que desea hacer coincidir las ubicaciones, sin mencionar que aparentemente hay impactos en el rendimiento de expresiones regulares en algunos casos.

La principal ventaja de incluir archivos (por lo que puedo decir) es que es un poco más flexible sobre exactamente lo que puede incluir: no tiene que ser un bloque de ubicación completo, por ejemplo. Pero también es subjetivamente un poco más complicado que las ubicaciones con nombre.

También tenga en cuenta que existe una solución relacionada que puede usar en situaciones similares: ubicaciones anidadas. La idea es que comience con una ubicación muy general, aplique alguna configuración común a varias de las posibles coincidencias y luego tenga ubicaciones anidadas separadas para los diferentes tipos de rutas que desea hacer coincidir. Por ejemplo, podría ser útil hacer algo como esto:

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

Este es un enfoque corto, pero eficiente y probado:

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

Por lo tanto, uno puede tener fácilmente múltiples patrones con una sintaxis de tubería simple que apunta al mismo bloque de ubicación / reglas.

Stamster
fuente