Express.js रूटिंग: वैकल्पिक स्पैट परम?


82

मेरे पास एक मार्ग है जो इस तरह दिखता है:

app.all('/path/:namedParam/*splat?',function(req,res,next){
  if(!req.params.length){
    // do something when there is no splat
  } else {
    // do something with splat
  }
});

हालाँकि, यह काम नहीं करता है - अगर मैं कहता हूं कि path/foo/barयह मार्ग हिट करता है, लेकिन अगर मैं फोन path/fooकरता हूं , तो यह नहीं है।

क्या एक वैकल्पिक स्पैट पैराम होना संभव है, या क्या मुझे इसका पता लगाने के लिए एक रेगेक्स का उपयोग करना होगा?

संपादित करें :

स्पष्ट होने के लिए, यहां वे आवश्यकताएं हैं जिन्हें मैं प्राप्त करने की कोशिश कर रहा हूं:

  • पहले और दूसरे परिम की आवश्यकता होती है
  • पहला परम स्थिर है, दूसरा नाम एक परम है।
  • वैकल्पिक अतिरिक्त पैरा की किसी भी संख्या को जोड़ा जा सकता है और अभी भी मार्ग मारा जा सकता है।

1
तुम क्या करने की कोशिश कर रहे हो? अगर आपको स्पैट जानने की जरूरत नहीं है, तो बस करें '/path/:firstParam/*'। यदि आपको इसकी आवश्यकता है, तो करें '/path/:firstParam/:secondParam?/*'
जोनाथन ओंग

1
मैं देख रहा हूँ कि वैकल्‍पिक होना वैकल्पिक है - पहला उदाहरण जो आपने दिया था वह मेल नहीं खाएगा /path/foo, (यह वही है जो मेरा रूट मूल रूप से वैसा ही दिखता था जैसा कि मैं वैकल्पिक स्‍पैट चाहता था)। इसके अतिरिक्त, आपके दूसरे उदाहरण में, स्पैट को जोड़ना वास्तव में वैकल्पिक दूसरे पैराम को नकारता है - /path/fooआपके दूसरे पैटर्न से मेल नहीं खाएगा (न ही /path/foo/barउस मामले के लिए ...) - एक्सप्रेस के राउटर के अधिक कष्टप्रद भागों में से एक।
जेसी

1
व्यक्तिगत रूप से मैं सिर्फ के लिए जाना होगा /path/:firstParamऔर /path/:firstParam/:secondParam/एक साझा नियंत्रक के साथ दो अलग-अलग रूटर के रूप में। अपने यूरल्स को भ्रमित करने की आवश्यकता नहीं है
जोनाथन ओएनजी

बीत रहा nहै एक विकल्प (यकीन है कि, मैं 10 अंतिमबिंदुओं बना सकते हैं नहीं, मैं सिर्फ 1-3 पैरामीटर के लिए मार्ग नहीं कर रहा हूँ, यह किसी भी संख्या हो सकती है, इसलिए पैरामीटर की संख्या पर कोई सीमा होने - अंतिमबिंदुओं एप्लिकेशन के डिजाइन के लिए आवश्यक है लेकिन यह व्यक्त करने से वह कार्य किसी मार्ग में करने से बेहतर नहीं है)। मैं अपनी समस्या को हल करने के लिए एक रेगेक्स मार्ग का उपयोग कर सकता हूं (जो मैं अभी कर रहा हूं), लेकिन मैं एक पठनीय विकल्प होने की उम्मीद कर रहा था।
जेसी

यह आश्चर्यजनक है कि देवता वैकल्पिक नाम के लिए केवल कोष्ठक का उपयोग करने के लिए नहीं सोचते थे। यानी/path/:param(/:otherOptionalParam)
r3wt

जवाबों:


111

यह एक्सप्रेस 4 पर / पथ और / पथ / फू के लिए काम करता है, *पहले ध्यान दें ?

router.get('/path/:id*?', function(req, res, next) {
    res.render('page', { title: req.params.id });
});

43
ध्यान दें कि जब काम करता है, अगर आप यात्रा /path/foo/bar/bazzle, req.params.idके बराबर होगा foo, और req.params[0]बराबर होगा /bar/bazzle, कुछ लोगों को ऊपर ट्रिप हो सकता है। एक क्लीनर समाधान पथ को परिभाषित करने के लिए हो सकता है /path/*?, जो कि एक्सप्रेस 4 में सेट req.params[0]हो जाएगा foo/bar/bazzle, जो संभवतः वह है जो आप देख रहे हैं।
जेसी

यदि आप अपने वैकल्पिक पैरामीटर को बेहतर तरीके से यूआरएल एन्कोडिंग करते हैं - स्लैश के साथ कुछ भी अनुमति देने का मतलब है कि आप सड़क के नीचे संघर्षों में भाग लेंगे यदि आप ऐप की तरह एक पथ जोड़ना चाहते हैं ('पथ /: आवश्यक 1 /: आवश्यक 2 /: वैकल्पिक? *' , हैंडलर)
जॉर्डन

@ अंतिम भाग को आवश्यक बनाने के लिए कोई भी तरीका? उदाहरण के लिए मैं मैच करना चाहता हूं /path/foo/barलेकिन नहीं /path/foo । मैंने कोशिश की '/path/:id/*लेकिन *खाली स्ट्रिंग से भी मेल खाता हुआ लगता है।
फ्रैंकलिन यू

73

मुझे बस यही समस्या थी और इसे हल किया। यह वही है जो मैंने इस्तेमाल किया:

app.get('path/:required/:optional?*', ...)

इस के लिए काम करना चाहिए path/meow, path/meow/voof, path/meow/voof/moo/etc...

यह /बीच में छोड़ने से लगता है ?और *, अंतिम /वैकल्पिक हो जाता है जबकि :optional?वैकल्पिक रहता है।


ठंडा! मैंने अभी इसका परीक्षण किया है (एक्सप्रेस 3.0.0 में, 2.x में परीक्षण नहीं किया गया है) और यह काम करता है। यह निश्चित रूप से मेरे RegEx हैक की तुलना में क्लीनर है।
जेसी

5
क्या आप जानते हैं कि मैं इन पूर्वनिर्धारित खोजशब्दों के बारे में और कहाँ पढ़ सकता हूँ?
जानोस

8
4.0x

2
@chris ने एक्सप्रेस 4 के लिए इसका उत्तर दिया - क्योंकि यह नवीनतम है, मैंने उसके उत्तर को स्वीकार कर लिया।
जेसी

इसका उपयोग करने में एक अजीब त्रुटि हुई, इसमें शून्य के साथ संख्याओं के लिए, एक्सप्रेस इसे काट देगा। उदाहरण के लिए /: आईडी जहां आईडी = 904, req.params.id = 9 और req.params.0 = 04 (किसी कारण से इस आराम को यहां व्यक्त करें)। क्रिस का जवाब इसे ठीक करता है
ईमिडी

17

क्या यह वह होगा जो आप कर रहे हैं?

app.all('/path/:namedParam/:optionalParam?',function(req,res,next){
  if(!req.params.optionalParam){
    // do something when there is no optionalParam
  } else {
    // do something with optionalParam
  }
});

एक्सप्रेस 'राउटिंग पर अधिक, अगर आपने नहीं देखा है: http://expressjs.com/guide/rout.html


2
यह समाधान मेल खाएगा /path/foo/bar, लेकिन नहीं /path/foo/bar/baz- *स्पैट मैच .+, जो मैं कर रहा हूं उसके लिए आवश्यक है - मैंने निश्चित रूप से आरटीएफएम किया है, इसका उल्लेख नहीं करता है, इसलिए शायद यह संभव नहीं है ...
जेसी

3

यहाँ वर्तमान तरीका है जो मैं इस समस्या को हल कर रहा हूँ, यह प्रकट नहीं होता है कि एक्सप्रेस किसी भी संख्या में अतिरिक्त पैरा नाम के विकल्प के साथ समर्थन करता है:

app.all(/\/path\/([^\/]+)\/?(.+)?/,function(req,res,next){
  // Note: this is all hacked together because express does not appear to support optional splats.
  var params = req.params[1] ? [req.params[1]] : [],
      name = req.params[0];
  if(!params.length){
    // do something when there is no splat
  } else {
    // do something with splat
  }
});

मैं इस उपयोग को पठनीयता और स्थिरता के लिए परमर्स नाम देना पसंद करूंगा - अगर कोई अन्य उत्तर सतहों जो इसे अनुमति देता है तो मैं इसे स्वीकार करूंगा।


2

मान लीजिए कि आपके पास यह url है: /api/readFile/c:/a/a.txt

यदि आप बनना चाहते req.params.pathहैं c::

'/api/readFile/:path*

यदि आप बनना चाहते req.params.pathहैं c:/a/a.txt:

'/api/readFile/:path([^/]*)'

0

वैकल्पिक का उपयोग करने वाले उपरोक्त समाधान एक्सप्रेस 4 में काम नहीं करते हैं। और मैंने खोज पैटर्न का उपयोग करते हुए कुछ तरीके आजमाए, लेकिन काम नहीं कर रहा है। और फिर मुझे यह विधि मिली और असीमित नेस्टेड पथ के लिए निकाल दिया गया, http://expressjs.com/api.html#router

// this will only be invoked if the path starts with /bar from the mount point
router.use('/bar', function(req, res, next) {
  // ... maybe some additional /bar logging ...

  // to get the url after bar, you can try
  var filepath = req.originalUrl.replace(req.baseUrl, "");

  next();
});

यह सभी / बार, / बार / जेड, / बार / ए / बी / सी आदि से मेल खाता है और उसके बाद, आप req.originalUrl पढ़ सकते हैं, क्योंकि परम नहीं भरे गए हैं, पूर्व। आप शेष पथ प्राप्त करने के लिए baseUrl और ओरिजिनल की तुलना करने का प्रयास कर सकते हैं।


0

मैंने एक मिडलवेयर के संयोजन का उपयोग करके इस समस्या को हल किया router.get('/bar/*?', ...जो url और , जो बाद में सब कुछ उठा लेगा /bar/, और undefinedयदि यह ठीक है , तो जोड़ देगा /bar/। यदि आगंतुक ने पूछा है /bar, तो express-slashमिडलवेयर अनुरोध में एक स्लैश जोड़ देगा और अनुरोध को बदल देगा /bar/

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