Saya memiliki aplikasi web yang sedang berjalan di http://example.com/
, dan ingin "me-mount" aplikasi lain, di server terpisah http://example.com/en
. Server upstream dan proxy_pass
tampaknya berfungsi, tetapi untuk satu masalah:
upstream luscious {
server lixxxx.members.linode.com:9001;
}
server {
root /var/www/example.com/current/public/;
server_name example.com;
location /en {
proxy_pass http://luscious;
}
}
Saat dibuka example.com/en
, aplikasi hulu saya kembali 404 not found /en
. Ini masuk akal, karena hulu tidak memiliki jalan /en
.
Apakah proxy_path
solusi yang tepat? Haruskah saya menulis ulang "upstream" sehingga ia mendengarkan /en
sebagai gantinya, karena root jalan? Atau adakah arahan yang memungkinkan saya untuk menulis ulang jalan yang dilalui untuk hulu?
proxy_pass
adalah apa yang membuat perbedaan. Juga, jawaban ini lebih benar daripada yang Anda ajukan, karena juga memastikan bahwaproxy_redirect
tetapdefault
, jadi, Anda masih bisa menggunakan302
et al di backend Anda, dan membuatnya bekerja dengan benar di mana-mana.Saya ingin membahas jawaban berbasis regex baru yang semakin populer.
Solusinya mungkin tampak lebih lucu pada pandangan pertama, tetapi itu salah karena berbagai alasan.
Regex di atas akan cocok dengan permintaan uri
/enjoy
, mengarahkannya ke/joy
hulu. Apakah ini benar-benar dimaksudkan?Permintaan untuk
/en
tidak akan menghasilkan arahan ulang, langsung melayani/
dari hulu (hampir seolah-olah permintaan/en/
dibuat sebagai gantinya, tetapi tidak cukup). Jika Anda menggunakan URI relatif di dalam halaman akar Anda di bagian hulu (jika tidak, mengapa Anda tidak akan memiliki/en/
awalan di sana dalam URI bagian hulu?), Misalnyasrc="style.css"
(yang mungkin merujuk pada bahasa tertentuurl("menu.png")
, misalnya), maka browser akan meminta agar sebagai/style.css
gantinya/en/style.css
. (Atau bahkan jika Anda menggunakan URI absolut di mana-mana, bagaimana jika seseorang mereferensikan sumber semi-opsional semi-relatif relatif?) Ups, tiba-tiba situs mungkin tidak berfungsi, tetapi hanya kadang-kadang atau dalam kasus tepi.Sesuai saran saya sebelumnya pada pertanyaan lain yang telah disebutkan oleh jawaban OP sendiri , menggunakan ekspresi reguler mencegah
proxy_redirect
arahan dari memiliki nilai defaultdefault
,off
sebaliknya menolaknya . Ini berarti bahwa jika upstream menjawabLocation: http://127.0.0.1:8080/en/dir/
ketika permintaan/en/dir
dibuat, maka itulah yang akan dilihat klien, yang jelas tidak akan berfungsi dengan benar. (Yang akan sangat ironis untuk/en
permintaan yang meminta penggunaan regex di tempat pertama, namun implementasi spesifik ini justru menderita masalah lain seperti yang telah disebutkan di atas.) Plus, jika Anda sudah menggunakanupstream
arahan, maka itu mungkin akan menjadi lebih jelek jika Anda hanya mencoba untuk pergi dengan yang khusus, terutama jika Anda mungkin memiliki lebih dari satu server hulu - bagaimana Anda memiliki yang terpisahproxy_redirect
untuk masing-masing? Anda dapat menggunakan ekspresi reguler di dalamproxy_redirect
, juga, mungkin bahkan untuk mencocokkan host mana pun, tetapi lalu bagaimana jika Anda memutuskan untuk memberikan pengalihan lintas-domain di masa mendatang?Untuk mencoba mengatasi beberapa poin di atas dengan satu lokasi berbasis regex, kita bisa melakukan hal berikut (perhatikan bahwa
proxy_pass
kita juga harus membuang referensi ke server dariupstream
direktif berbasis, untuk membuatnyaproxy_redirect
lebih mudah):Jadi, jika Anda bertanya kepada saya, solusi asli dengan dua lokasi tingkat atas saudara kandung masih akan menjadi ide yang lebih baik daripada menggali diri Anda ke dalam lubang kelinci dengan pergi rute regex sebagai gantinya.
sumber
nginx: [emerg] location "/en" is outside location "^/en/?((?<=/).*
Jadi, saya menemukan jawabannya di stackoverflow :
Pada dasarnya: meneruskan regex ke lokasi dan meneruskan backref ke url proxy_pass.
sumber
Akuntansi ke dokumen Nginx
Untuk meneruskan permintaan ke server proxy HTTP, proxy_pass direktif ditentukan di dalam lokasi. Sebagai contoh:
Contoh konfigurasi ini menghasilkan melewati semua permintaan yang diproses di lokasi ini ke server proksi di alamat yang ditentukan. Alamat ini dapat ditentukan sebagai nama domain atau alamat IP. Alamat tersebut juga dapat mencakup port:
Perhatikan bahwa pada contoh pertama di atas, alamat server proksi diikuti oleh URI, / tautan /. Jika URI ditentukan bersama dengan alamat, itu menggantikan bagian dari permintaan URI yang cocok dengan parameter lokasi. Misalnya, di sini permintaan dengan Us /some/path/page.html akan diproksi ke http://www.example.com/link/page.html . Jika alamat tersebut ditentukan tanpa URI, atau tidak mungkin untuk menentukan bagian URI yang akan diganti, URI permintaan penuh diteruskan (mungkin, dimodifikasi).
sumber