Nginx प्रॉक्सी_पास के साथ पथ को कैसे निकालें


77

मेरे पास एक चालू वेब-एप्लिकेशन है http://example.com/, और एक अलग सर्वर पर एक और एप्लिकेशन को "माउंट" करना चाहते हैं http://example.com/en। अपस्ट्रीम सर्वर और proxy_passकाम करने के लिए लगता है, लेकिन एक मुद्दे के लिए:

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;
  }
}

खोलते समय example.com/en, मेरा अपस्ट्रीम एप्लिकेशन वापस आ जाता है 404 not found /en। यह समझ में आता है, क्योंकि ऊपर की तरफ रास्ता नहीं है /en

है proxy_pathसही समाधान? क्या मुझे "अपस्ट्रीम" को फिर से लिखना चाहिए ताकि /enयह रूट पथ के रूप में सुनता है ? या क्या कोई निर्देश है जो मुझे अपस्ट्रीम के साथ पारित मार्ग को फिर से लिखने की अनुमति देता है?

जवाबों:


133

किसी भी नियमित अभिव्यक्ति के उपयोग के बिना, आप जो चाहते हैं, वह करने का यह सबसे कारगर तरीका है:

location = /en {
    return 302 /en/;
}
location /en/ {
    proxy_pass http://luscious/;  # note the trailing slash here, it matters!
}

1
जहाँ तक मुझे पता है, अंतिम भाग अभी भी "/ en" के रूप में प्रॉक्सी के साथ पथ पर जाएगा, नहीं?
Berkes

15
@berkes, नहीं, यह नहीं होगा - अनुगामी स्लैश में proxy_passक्या फर्क पड़ता है। इसके अलावा, यह उत्तर आपके द्वारा आए एक से अधिक सही है, क्योंकि यह यह भी सुनिश्चित करता है कि इस पर proxy_redirectरहता है default, इसलिए, आप अभी भी 302अपने बैकएंड के भीतर एट अल का उपयोग कर सकते हैं , और यह हर जगह सही ढंग से काम करता है।
cnst

4
आह, मैं अनुगामी स्लैश याद कर रहा था :(
वानुआन

3
Aaargh! अनुगामी स्लेश !
बैरीमाक

4
खोज के 3 घंटे, और हाँ ... यह अनुगामी स्लेश था। धन्यवाद दोस्त!
लुकास पी।

12

मैं एक नए regex- आधारित उत्तर को संबोधित करना चाहूंगा जो लोकप्रियता में बढ़ रहा है।

location ~ ^/en(/?)(.*)$ {  # OOPS!
  proxy_pass http://luscious/$2$is_args$args;  # OOPS!
}

पहली नज़र में समाधान अधिक प्यारा लग सकता है, लेकिन कई कारणों से यह गलत है।

  • उपरोक्त रेगेक्स एक आग्रह करता हूं कि यूआई से /enjoy, इसे /joyअपस्ट्रीम पर पुनर्निर्देशित करेगा । क्या यह वास्तव में इरादा है?

  • /enकिसी भी पुनर्निर्देश के लिए अनुरोध का परिणाम नहीं होगा, सीधे /अपस्ट्रीम से सेवा करना (लगभग जैसे कि /en/इसके बजाय एक अनुरोध किया गया था, लेकिन काफी नहीं)। यदि आप अपने मूल पृष्ठ के ऊपर (अन्यथा, आपके पास /en/उपसर्ग URI के भीतर उपसर्ग क्यों नहीं होगा ?), उदाहरण के लिए src="style.css"(जो भाषा-विशेष का संदर्भ दे सकता है url("menu.png"), उदाहरण के लिए), तो ब्राउज़र अनुरोध करेगा कि के /style.cssबजाय के रूप में /en/style.css। (या यहां तक ​​कि अगर आप हर जगह निरपेक्ष यूआरआई का उपयोग करते हैं, तो क्या होगा यदि कोई व्यक्ति एक अस्पष्ट अर्ध-वैकल्पिक संसाधन का संदर्भ देता है?) ओह, अचानक साइट काम नहीं कर सकती है, लेकिन केवल कभी-कभी या किनारे के मामलों में।

  • ओपी के स्वयं के जवाब द्वारा पहले से ही उल्लेखित एक अन्य प्रश्न पर मेरी पहले की सलाह के अनुसार , नियमित अभिव्यक्तियों का उपयोग करने से proxy_redirectनिर्देश को डिफ़ॉल्ट मान होने से रोकता है default, इसे offबदले में बदल देता है । इसका मतलब यह है कि यदि अपस्ट्रीम जवाब देता है Location: http://127.0.0.1:8080/en/dir/जब अनुरोध किया /en/dirजाता है, तो वह वही होगा जो ग्राहक देखेंगे, जो स्पष्ट रूप से सही ढंग से काम नहीं करेगा। (जो विशेष रूप से एक /enअनुरोध के लिए विडंबनापूर्ण होगा जो पहले स्थान पर रेगेक्स के उपयोग को बढ़ावा देता है, फिर भी यह विशिष्ट कार्यान्वयन इसके बजाय पहले से ही उल्लेखित एक अन्य समस्या से ग्रस्त है।) प्लस, यदि आप पहले से ही उपयोग कर रहे हैं।upstreamनिर्देश, तो यह अतिरिक्त बदसूरत हो सकता है यदि आप सिर्फ एक कस्टम के साथ जाने की कोशिश करते हैं, खासकर यदि आपके पास एक से अधिक अपस्ट्रीम सर्वर हो सकते हैं - तो आप proxy_redirectउनमें से प्रत्येक के लिए एक अलग कैसे हो सकते हैं ? आप proxy_redirectकिसी भी होस्ट से मेल खाने के लिए भी, शायद नियमित अभिव्यक्ति का उपयोग कर सकते हैं , लेकिन तब क्या होगा यदि आप भविष्य में क्रॉस-डोमेन रीडायरेक्ट देने का निर्णय लेते हैं?

एकल रेगेक्स-आधारित स्थान के साथ उपर्युक्त कुछ बिंदुओं को संबोधित करने का प्रयास करने के लिए, हम निम्नलिखित कर सकते हैं (ध्यान दें कि proxy_passहमें सर्वर से संदर्भ को upstreamनिर्देश देने के लिए proxy_redirectभी निर्देश दिया गया था, अधिक सीधा बनाने के लिए ):

location ~ ^/en/?((?<=/).*)?$ {
  location = /en { return 302 /en/; }
  proxy_pass http://127.0.0.1:8080/$1$is_args$args;
  proxy_redirect http://127.0.0.1:8080/ /en/;
}

इसलिए, यदि आप मुझसे पूछें, तो दो सिबलिंग शीर्ष-स्तरीय स्थानों के साथ मूल समाधान अभी भी एक बेहतर विचार होगा जो रेगेक्स मार्ग में जाने के बजाय अपने आप को एक खरगोश छेद में खोदने से बेहतर होगा।


यह एक अपवाद का कारण बनता है:nginx: [emerg] location "/en" is outside location "^/en/?((?<=/).*
एथलन

1
@ एंथलन, ऐसा इसलिए है क्योंकि आपको वास्तव में पहली जगह में इसका उपयोग नहीं करना चाहिए! यदि आप अभी भी चाहते हैं, तो आप उस स्थान को regexp के बाहर रख सकते हैं।
cnst

स्थानीयकरण लगाना = बाहर काम करना वास्तव में ठीक है! धन्यवाद
सेबेस्टियन वेबर

7

तो, मुझे स्टैकओवरफ्लो पर जवाब मिला :

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/$2;
  }
}

मूल रूप से: एक रेगेक्स को स्थान में पास करना और प्रॉक्सी_पास url के साथ बैकएफ़ को पास करना।


मुझे लगता है कि "प्रॉक्सी_पास सुस्वाद / $ ;" होना चाहिए "proxy_pass सुस्वाद / $ 2 "
Zafer

1
@Zafer सही है, उपरोक्त जवाब मुझे एक त्रुटि दे रहा था
फ्रैंक ५

मैंने उत्तर बदल दिया है, लेकिन मेरे पास एक सर्वर नहीं है जहां मैं यह कोशिश कर सकता हूं, एटीएम, इसलिए यह सत्यापित नहीं है।
बजे

0

Nginx दस्तावेजों के लिए लेखांकन

HTTP प्रॉक्सी सर्वर से अनुरोध पारित करने के लिए, प्रॉक्सी_पास का निर्देश किसी स्थान के अंदर निर्दिष्ट किया गया है। उदाहरण के लिए:

location /some/path/ {
    proxy_pass http://www.example.com/link/;
}

इस उदाहरण कॉन्फ़िगरेशन में निर्दिष्ट पते पर इस स्थान पर संसाधित सर्वर में सभी अनुरोधों को पारित करने का परिणाम है। इस पते को एक डोमेन नाम या एक आईपी पते के रूप में निर्दिष्ट किया जा सकता है। पते में एक पोर्ट भी शामिल हो सकता है:

location ~ \.php {
    proxy_pass http://127.0.0.1:8000;
}

ध्यान दें कि ऊपर दिए गए पहले उदाहरण में, प्रॉक्सी सर्वर का पता URI, / लिंक / के बाद है। यदि पते के साथ URI निर्दिष्ट किया गया है, तो यह अनुरोध URI के उस भाग को प्रतिस्थापित करता है जो स्थान पैरामीटर से मेल खाता है। उदाहरण के लिए, यहां /some/path/page.html URI के साथ अनुरोध http://www.example.com/link/page.html पर अनुमानित होगा । यदि पता URI के बिना निर्दिष्ट किया गया है, या URI के भाग को प्रतिस्थापित करने के लिए निर्धारित करना संभव नहीं है, तो पूर्ण अनुरोध URI पारित हो जाता है (संभवतः, संशोधित)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.