Sorgu dizesi parametreleri nginx ile bir proxy_pass aracılığıyla nasıl iletilebilir?


114
upstream apache {
   server 127.0.0.1:8080;
}
server{
   location ~* ^/service/(.*)$ {
      proxy_pass http://apache/$1;
      proxy_redirect off;
   }
 }

Yukarıdaki kod parçası, url'nin "hizmet" dizesini içerdiği istekleri başka bir sunucuya yönlendirir, ancak sorgu parametrelerini içermez.

Yanıtlar:


163

Gönderen proxy_pass belgelerinde:

Proxy_pass deyiminde değişkenlerin kullanılması özel bir durumdur: İstenen URL kullanılmaz ve hedef URL'yi kendiniz oluşturmaktan tamamen siz sorumlusunuz.

Hedefte 1 dolar kullandığınız için, nginx size tam olarak neyi geçeceğini söyleme konusunda güvenir. Bunu iki şekilde düzeltebilirsiniz. İlk olarak, uri'nin başlangıcını proxy_pass ile çıkarmak önemsizdir:

location /service/ {
  # Note the trailing slash on the proxy_pass.
  # It tells nginx to replace /service/ with / when passing the request.
  proxy_pass http://apache/;
}

Veya normal ifade konumunu kullanmak istiyorsanız, sadece bağımsız değişkenleri ekleyin:

location ~* ^/service/(.*) {
  proxy_pass http://apache/$1$is_args$args;
}

1
İkincisini yapabileceğine inanmıyorum. Denedim ve nginx bana şikayet etti.
duma

3
Nasıl şikayet ettiniz? Sadece nginx 1.3.4'te test ettim ve benim için iyi çalıştı.
kolbyjack

Humm .. Şimdi hatırlayamıyorum :( Ama "~ *" ile ilgili olabileceğini hissediyorum. Ancak, daha yeni kontrol ettim ve nginx 1.2.3 (homebrew aracılığıyla) olabilir. Belki de budur?
duma

"proxy_redirect default" değişkenlerle "proxy_pass" yönergesi ile kullanılamaz
Jean-Philippe Caruana

1
yeniden yazmayı kullanmak zorunda location /service/ { rewrite ^\/service\/(.*) /$1 break; proxy_pass http://apache; }
Andrew Arnautov

27

Kolbyjack'in ikinci yaklaşımının ~yerine biraz değiştirilmiş bir versiyonunu kullanıyorum ~*.

location ~ ^/service/ {
  proxy_pass http://apache/$uri$is_args$args;
}

10

@Kolbyjack kodunu, bunun için çalışması için değiştirdim

http://website1/service
http://website1/service/

parametrelerle

location ~ ^/service/?(.*) {
    return 301 http://service_url/$1$is_args$args;
}

1
Bunun, sunucunun yeniden yönlendirmeden önce istemciye bir 301 yanıtı döndürmesini sağlayacağını unutmayın. Yukarıdaki proxy_passyönerge sunucu tarafında yeniden yönlendirmeyi yapar.
Luke Peterson

1
Sorgu parametreleriniz URL (%) olarak kodlanmış karakterler içeriyorsa, bu bozulacaktır. Bunun yerine Andrew'un cevabını kullanın.
David Weber

9

proxy_pass kullanarak parametreleri geçmek için yeniden yazma kullanmanız gerekir, burada örnek s3'e angularjs uygulaması dağıtımı için yaptığım bir örnek

S3 Statik Web Sitesi Barındırma Tüm Yolları Index.html'ye Yönlendirin

ihtiyaçlarınıza göre benimsenmiş gibi bir şey olurdu

location /service/ {
    rewrite ^\/service\/(.*) /$1 break;
    proxy_pass http://apache;
}

http://127.0.0.1:8080/query/params/ ile sonlandırmak istiyorsanız

Eğer sonuna kadar istiyorum http://127.0.0.1:8080/service/query/params/ gibi bir şey gerekir

location /service/ {
    rewrite ^\/(.*) /$1 break;
    proxy_pass http://apache;
}

1
Bu, yol parametrelerini ( /path/params) iyi işliyor gibi görünüyor, ancak params ( ?query=params) sorgusunu yapmıyor mu?
Will

Ah hayır, hatam, sorgu parametreleri otomatik olarak eklenmeli (bunlar benim testimde).
Will

2

github gist https://gist.github.com/anjia0532/da4a17f848468de5a374c860b17607e7

#set $token "?"; # deprecated

set $token ""; # declar token is ""(empty str) for original request without args,because $is_args concat any var will be `?`

if ($is_args) { # if the request has args update token to "&"
    set $token "&";
}

location /test {
    set $args "${args}${token}k1=v1&k2=v2"; # update original append custom params with $token
    # if no args $is_args is empty str,else it's "?"
    # http is scheme
    # service is upstream server
    #proxy_pass http://service/$uri$is_args$args; # deprecated remove `/`
    proxy_pass http://service$uri$is_args$args; # proxy pass
}

#http://localhost/test?foo=bar ==> http://service/test?foo=bar&k1=v1&k2=v2

#http://localhost/test/ ==> http://service/test?k1=v1&k2=v2

1

Sorgu Dizesi Olmadan yeniden yönlendirmek için, dinleme bağlantı noktası satırı altındaki Sunucu bloğundaki aşağıdaki satırları ekleyin:

if ($uri ~ .*.containingString$) {
           return 301 https://$host/$uri/;
}

Sorgu Dizesi ile:

if ($uri ~ .*.containingString$) {
           return 301 https://$host/$uri/?$query_string;
}

1
Nginx belgeleri, ifmümkün olduğunda kullanmaktan kaçınmak için açıktır . Bu durumda, çözüm locationbaşka bir cevapta gösterildiği gibi doğru kullanım olabilir .
Andrés Morales

2
her neyse, sakıncaları olsa bile bir çözüm daha iyidir
Dmitry Malugin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.