सवाल Nginx रिवर्स प्रॉक्सी + यूआरएल पुनः लिखना


Nginx पोर्ट 80 पर चल रहा है, और मैं पथ के साथ प्रॉक्सी यूआरएल को रिवर्स करने के लिए इसका उपयोग कर रहा हूं /foo बायें तरफ़ मुड़ने के लिए 3200 इस तरफ:

location /foo {
                proxy_pass http://localhost:3200;
                proxy_redirect     off;
                proxy_set_header   Host $host;
}

यह ठीक काम करता है, लेकिन मेरे पास बंदरगाह पर एक आवेदन है 3200, जिसके लिए मैं प्रारंभिक नहीं चाहता /foo भेजा जाना है। वह है - जब मैं पहुंचता हूं http://localhost/foo/bar, मुझे केवल चाहिए /bar ऐप द्वारा प्राप्त पथ होने के लिए। तो मैंने उपरोक्त स्थान ब्लॉक में इस पंक्ति को जोड़ने का प्रयास किया:

rewrite ^(.*)foo(.*)$ http://localhost:3200/$2 permanent;

यह 302 रीडायरेक्ट (यूआरएल में परिवर्तन) का कारण बनता है, लेकिन मुझे 301 चाहिए। मुझे क्या करना चाहिए?


95
2018-04-15 17:31


मूल


यदि आपको ग्राफाना मामले में कोई समस्या है तो आपको इन नुस्खा का उपयोग करना चाहिए: docs.grafana.org/installation/behind_proxy/... - mohsen saeedi


जवाब:


लोकलहोस्ट पर कोई भी रीडायरेक्ट रिमोट सिस्टम (उदा। क्लाइंट का वेब ब्राउजर) से समझ में नहीं आता है। ऐसा झंडे को फिर से लिखो स्थायी (301) या रीडायरेक्ट (302) आपके मामले में प्रयोग योग्य नहीं हैं।

एक पारदर्शी पुनर्लेखन नियम का उपयोग कर सेटअप का पालन करने का प्रयास करें:

location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $host;
}

उपयोग curl -i अपने पुनर्लेखन का परीक्षण करने के लिए। नियम में एक बहुत सूक्ष्म परिवर्तन nginx को रीडायरेक्ट करने का कारण बन सकता है।


117
2018-04-15 17:56



यूआरएल पथ अभी भी मेरे ऐप में / foo के साथ शुरू होता है जब मैं ऐसा करता हूं ... - jeffreyveon
एक अलग समस्या होनी चाहिए। मैंने इस परिदृश्य को कुछ मिनट पहले सफलतापूर्वक पुन: उत्पन्न किया था। मूल यूआरएल: http: // विकास / foo / testme / 1234 - प्रॉक्सी बैक-एंड के रूप में जुड़े अपाचे पर चल रही एक PHP स्क्रिप्ट का REQUEST_URI: '/ testme / 1234' - Jens Bradler
Regex शायद होना चाहिए /foo(.*), अन्यथा example.com/foo मिलान नहीं किया जाएगा। (जो शायद जेफरीवेन अनुभवी है) - Benno
इस तरह के काम, लेकिन मेरा शरीर मैं proxy_set_body के साथ सेटिंग कर रहा हूँ हटा दिया जा रहा है। - Justin Thomas
पुनः लिखें /(.*) /socket.io/ ब्रेक; SOCKET.IO के लिए मेरा दिन बचाओ - user956584


जब तक आप प्रॉक्सी_पास निर्देश में यूआरआई निर्दिष्ट करते हैं, तब तक एक सरल स्थान उपसर्ग मिलान के लिए इसके लिए सरल स्थान उपसर्ग मिलान कार्य करता है:

location /foo {
  proxy_pass http://localhost:3200/;
}

अतिरिक्त ध्यान दें / के अंत में proxy_pass निर्देश। एनजीआईएनएक्स मिलान किए गए उपसर्ग को पट्टी करेगा /foo और शेष को यूआरआई में बैकएंड सर्वर पर पास करें /। इसलिए, http://myserver:80/foo/bar बैकएंड पर पोस्ट करेंगे http://localhost:3200/bar

वहाँ से Proxy_pass पर एनजीआईएनएक्स दस्तावेज़:

यदि proxy_pass निर्देश यूआरआई के साथ निर्दिष्ट है, तो जब ए   अनुरोध सामान्य सर्वर अनुरोध यूआरआई का हिस्सा, सर्वर को पास किया जाता है   स्थान से मेल खाने के निर्देश में निर्दिष्ट यूआरआई द्वारा प्रतिस्थापित किया गया है:


86
2017-09-29 03:30



मेरे लिए काम करता है / स्थान / foo / { - Andrei N
यह वही था जो मैं खोज रहा था! - anbiniyar
यह एक बहुत ही साफ समाधान है, मैं इसे प्रश्न के वैधानिक उत्तर के रूप में पसंद करूंगा। - ralien
पिछली स्लैश को रखने या हटाने के महत्व को समझने में बहुत लंबा लगा। - Parvez
यह वास्तव में गुजर जाएगा //xyz मेजबान के लिए यदि आप ऐसा करते हैं। - Archimedes Trajano


पूर्णत: सबसे सही तरीका और सर्वोत्तम अभ्यास आमतौर पर निम्नानुसार है:

location /foo/ {
    proxy_pass http://localhost:3200/; # note the trailing slash!
}

  • के गंभीर महत्व पर ध्यान दें पीछे पीछे स्लैश proxy_pass, जो स्वचालित रूप से बदलता है $uri परिवर्तनीय है /foo/ सामने के अंत में अनुरूप है / बैकएंड पर। एक स्पष्ट के लिए कोई ज़रूरत नहीं है rewrite निर्देश।

  • इसके अतिरिक्त, ध्यान दें कि अनुगामी / में location इसके साथ-साथ काफी महत्वपूर्ण है - इसके बिना, आपको एक बिंदु पर अपनी साइट पर अजीब दिखने वाले यूआरएल होने का खतरा है (उदाहरण के लिए, एक काम करना /fooen के अतिरिक्त /foo/en)।

    इसके अतिरिक्त, पीछे की ओर / में location साथ में proxy_pass कुछ भी सुनिश्चित करता है विशेष हैंडलिंग, के दस्तावेज के अनुसार location प्रभावी रूप से एक अंतर्निहित कारण के लिए निर्देश location = /foo {return 301 /foo/;} भी।

    तो, एक परिभाषित करके location उपर्युक्त के रूप में पिछली स्लैश के साथ, आप न केवल यह सुनिश्चित करते हैं कि स्लैश-कम प्रत्यय URL जैसे /fooen मान्य नहीं होगा, बल्कि यह भी /foo बिना किसी पीछे की स्लैश के काम भी जारी रहेगा।


संदर्भ दस्तावेज:


30
2017-08-26 21:12



यह सबसे अच्छा जवाब है! - Mo Friedrich
ऐसा लग रहा है $args खो गये: http://frontend/foo?bar=baz के लिए प्रॉक्सी किया जाएगा http://backend/। ध्यान दें कि तर्क यूआरएल का हिस्सा नहीं हैं - Vanuan
@ वानुआन, क्या आप इसके बारे में निश्चित हैं? मैं बहुत निश्चित हूँ $args यदि आप ऊपर दिए गए कोड का उपयोग करते हैं, तो वे अभी भी उचित तरीके से संभाले जा सकते हैं, क्योंकि वे अलग हैं $uri, और जब तक आप अपने में स्पष्ट चर का उपयोग नहीं कर रहे हैं, तब तक इकट्ठा हो जाना चाहिए proxy_pass। - cnst
@ArchimedesTrajano, आप गलत हैं, क्योंकि इसके लिए विशेष हैंडलिंग है /foo रीडायरेक्ट करने के लिए /foo/, इसलिए, जब तक आप बैकएंड पर अजीब कुछ नहीं कर रहे हैं, यहां तक ​​कि /foo अनुरोध अभी भी उपरोक्त कोड के साथ काम करेंगे। (यह वास्तव में उत्तर का उत्तर है, बीटीडब्लू।) - cnst
यह सबसे अच्छा जवाब है! यह ऊपर जाना चाहिए। - phegde


प्रयत्न

location /foo {
    proxy_pass http://localhost:3200/;
    ....

या

location ^~ /foo {
    proxy_pass http://localhost:3200/;
    ....

0
2018-01-21 16:20



यह जवाब अच्छा होगा यदि आप कुछ स्पष्टीकरण देते हैं तो इसे ऊपर की तरह कॉन्फ़िगर क्यों किया जाना चाहिए। - masegaloeh
यह वास्तव में गुजर जाएगा //xyz मेजबान के लिए यदि आप ऐसा करते हैं। - Archimedes Trajano