NGINX'te bir proxy yanıtındaki URL'leri nasıl yeniden yazarım


87

Apache'yi mod_proxy_html ile kullanmaya alışkınım ve NGINX ile benzer bir şey elde etmeye çalışıyorum. Spesifik kullanım durumu, Tomcat'te kök bağlamında bir sunucuda 8080 bağlantı noktasında çalışan bir yönetici kullanıcı arayüzüne sahip olmamdır:

http://localhost:8080/

Bunu 80 numaralı bağlantı noktasında yüzeye çıkarmam gerekiyor, ancak bu ana bilgisayarda çalışan NGINX sunucusunda başka bağlamlarım var, bu yüzden denemek ve şu adresten erişmek istiyorum:

http://localhost:80/admin/

Aşağıdaki süper basit sunucu bloğunun bunu yapacağını umuyordum, ancak tam olarak değil:

server {
    listen  80;
    server_name screenly.local.akana.com;

    location /admin/ {
        proxy_pass http://localhost:8080/;
    }
}

Sorun, döndürülen içeriğin (html) tümü kök bağlamda erişilen komut dosyalarına ve stil bilgilerine URL'ler içermesidir, bu nedenle bu URL'leri / yerine / admin / ile başlayacak şekilde yeniden yazmam gerekiyor.

Bunu NGINX'te nasıl yaparım?

Yanıtlar:


128

Öncelikle proxy_pass üzerindeki belgeleri dikkatlice ve eksiksiz bir şekilde okumalıyız .

Yukarı akış sunucusuna iletilen URI, "proxy_pass" yönergesinin URI ile kullanılıp kullanılmadığına göre belirlenir. Proxy_pass yönergesinde sondaki eğik çizgi, URI'nin mevcut ve eşit olduğu anlamına gelir /. Sonda eğik çizgi olmaması, şapka URI'sinin olmadığı anlamına gelir.

URI ile Proxy_pass :

location /some_dir/ {
    proxy_pass http://some_server/;
}

Yukarıdakilerle aşağıdaki proxy var:

http:// your_server/some_dir/ some_subdir/some_file ->
http:// some_server/          some_subdir/some_file

Temelde, /some_dir/yerini alır /gelen istek yolunu değiştirmek için /some_dir/some_subdir/some_fileiçin /some_subdir/some_file.

URI'sız Proxy_pass :

location /some_dir/ {
    proxy_pass http://some_server;
}

İkincisi ile (eğik çizgi yok): proxy şu şekilde gider:

http:// your_server /some_dir/some_subdir/some_file ->
http:// some_server /some_dir/some_subdir/some_file

Temel olarak, orijinal istek yolunun tamamı değişiklik yapılmadan aktarılır.


Öyleyse, senin durumunda, istediğini elde etmek için sondaki eğik çizgiyi bırakmalısın.


Uyarı

Otomatik yeniden yazmanın yalnızca proxy_pass içinde değişkenler kullanmıyorsanız çalıştığını unutmayın. Değişkenler kullanıyorsanız, kendinizi yeniden yazmalısınız:

location /some_dir/ {
  rewrite    /some_dir/(.*) /$1 break;
  proxy_pass $upstream_server;
}

Yeniden yazmanın işe yaramayacağı başka durumlar da vardır, bu yüzden belgeleri okumak bir zorunluluktur.


Düzenle

Sorunuzu tekrar okuduktan sonra, html çıktısını düzenlemek istediğinizi kaçırmış olabilirim.

Bunun için sub_filter direktifini kullanabilirsiniz . Gibi bir şey ...

location /admin/ {
    proxy_pass http://localhost:8080/;
    sub_filter "http://your_server/" "http://your_server/admin/";
    sub_filter_once off;
}

Temel olarak, değiştirmek istediğiniz dize ve değiştirilecek dize


2
Teşekkürler, bu çok yardımcı oluyor. Sanırım sub_filter bunu yapacak.
IanG

2
Merak ediyorum, nginx'in çıktıyı zaten ne ölçüde yeniden yazdığını merak ediyorum, en azından bağlantılara ana bilgisayar / ana bilgisayar adını yeniden yazması gerekmiyor mu? Örneğin Yani, olmazsub_filter "http://localhost/" "http://localhost/admin/"
ThorSummoner

1
text/htmlMimetype dışında yeniden yazmaya izin vermek için ayrıca eklemek zorunda kaldım sub_filter_types *;.
anttikoo

Bu çözümle benim için tuhaf bir şeyler oluyor. Kaynaklar (* .js, * .css vb. Getiriliyor), ancak sayfa yüklenemiyor. i beklenebilir http://your_server/admin/için çözülmesi için http://your_serverproxy_pass sırasında ancak yok ve ben bir hata alıyorum react-router /admin/ location did not match any routesbaşvurum '/ yönetici' hakkında hiçbir şey bilmediği için benim uygulamada.
Prachi

Ayrıca , yanıt tarafından gönderilen başlığın da url'ye göre değiştirilebilmesi için proxy_redirectyönerge eklemeniz gerekebilir Location. Bu eğiticiye göz atın: cyberciti.biz/faq/…
vivanov

22

Veri sıkıştırmalı arka uç sunucular için aşağıdaki yönergenin ilk "alt_filter" den önce ayarlanması gerekebilir:

proxy_set_header Accept-Encoding "";

Aksi takdirde çalışmayabilir. Örneğiniz için şöyle görünecek:

location /admin/ {
    proxy_pass http://localhost:8080/;
    proxy_set_header Accept-Encoding "";
    sub_filter "http://your_server/" "http://your_server/admin/";
    sub_filter_once off;
}

-1

Aşağıdaki nginx yapılandırma örneğini kullanabilirsiniz:

upstream adminhost {
  server adminhostname:8080;
}

server {
  listen 80;

  location ~ ^/admin/(.*)$ {
    proxy_pass http://adminhost/$1$is_args$args;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $server_name;
  }
}

1
Bu neden reddedildi? Kodla ilgili bir sorun mu var? Daha sonra açılan bir uygulamanın proxy'sinin bazı uyarılarını çözerek bana güzel ve karmaşık bir çözüm gibi görünüyor. Neden olduğundan emin değilim proxy_redirect off;. Ben de eklerdim proxy_set_header X-Forwarded-Proto $scheme;.
LuH
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.