मैं कुछ संदर्भों को पारित करते समय एक्सप्रेस में पुनर्निर्देशित कैसे करूं?


269

मैं नोड में एक वेब ऐप बनाने के लिए एक्सप्रेस का उपयोग कर रहा हूं। जेसेज यह मेरे पास क्या है का एक सरलीकरण है:

var express = require('express');
var jade = require('jade');
var http = require("http");


var app = express();
var server = http.createServer(app);

app.get('/', function(req, res) {
    // Prepare the context
    res.render('home.jade', context);
});

app.post('/category', function(req, res) {
    // Process the data received in req.body
    res.redirect('/');
});

मेरी समस्या निम्नलिखित है:

अगर मुझे पता चलता है कि भेजा गया डेटा /categoryमान्य नहीं है, तो मैं /पृष्ठ पर कुछ अतिरिक्त संदर्भ देना चाहूंगा । मैं ये कैसे करूं? रीडायरेक्ट किसी भी प्रकार के अतिरिक्त पैरामीटर की अनुमति नहीं देता है।


1
एक्सप्रेस देखें ' flash: stackoverflow.com/questions/12442716/…
tymeJV

शब्दावली यहां मायने रखती है: कोई /पृष्ठ नहीं है । एक /मार्ग है, जो एक्सप्रेस सेवा कर सकता है, और एक मुखपृष्ठ टेम्पलेट है, जो एक्सप्रेस प्रस्तुत कर सकता है। यदि आप रीडायरेक्ट के बाद होमपेज टेम्प्लेट को रेंडर करने के लिए कुछ डेटा को संरक्षित करना चाहते हैं, तो स्वीकृत उत्तर के बावजूद, सत्र आपके मित्र हैं। वे आपको एक डेटा स्टोर देते हैं जो व्यक्तिगत ब्राउज़िंग उपयोगकर्ताओं के लिए अनुरोधों और प्रतिक्रियाओं के लिए बनी रहती है ताकि आप डेटा को /categoryहैंडलिंग के दौरान रख सकें , और फिर इसे हाथ से निकालने के दौरान बाहर निकाल दें /
माइक 'पोमैक्स' कामेरमेंस

जवाबों:


366

विभिन्न मार्गों के आसपास डेटा पास करने के कुछ तरीके हैं। सबसे सही जवाब, ज़ाहिर है, क्वेरी तार है। आप यह सुनिश्चित करें कि मान ठीक से कर रहे हैं की आवश्यकता होगी encodeURIComponent और decodeURIComponent

app.get('/category', function(req, res) {
  var string = encodeURIComponent('something that would break');
  res.redirect('/?valid=' + string);
});

आप उपयोग करके भेजे गए मापदंडों को प्राप्त करके अपने अन्य मार्ग में रोड़ा बना सकते हैं req.query

app.get('/', function(req, res) {
  var passedVariable = req.query.valid;
  // Do something with variable
});

अधिक गतिशील तरीके से आप अपने लिए urlक्वेरी स्ट्रिंग उत्पन्न करने के लिए कोर मॉड्यूल का उपयोग कर सकते हैं :

const url = require('url');    
app.get('/category', function(req, res) {
    res.redirect(url.format({
       pathname:"/",
       query: {
          "a": 1,
          "b": 2,
          "valid":"your string here"
        }
     }));
 });

इसलिए यदि आप सभी रीक क्वेरी स्ट्रिंग वैरिएबल को पुनर्निर्देशित करना चाहते हैं तो आप बस कर सकते हैं

res.redirect(url.format({
       pathname:"/",
       query:req.query,
     });
 });

और अगर आप Node> = 7.x का उपयोग कर रहे हैं तो आप querystringकोर मॉड्यूल का भी उपयोग कर सकते हैं

const querystring = require('querystring');    
app.get('/category', function(req, res) {
      const query = querystring.stringify({
          "a": 1,
          "b": 2,
          "valid":"your string here"
      });
      res.redirect('/?' + query);
 });

इसे करने का एक और तरीका सत्र में कुछ स्थापित करना है। आप इसे यहां सेट अप करने के लिए पढ़ सकते हैं , लेकिन चर सेट और एक्सेस करने के लिए कुछ इस तरह है:

app.get('/category', function(req, res) {
  req.session.valid = true;
  res.redirect('/');
});

और बाद में पुनर्निर्देशन के बाद ...

app.get('/', function(req, res) {
  var passedVariable = req.session.valid;
  req.session.valid = null; // resets session variable
  // Do something
});

वहाँ भी, एक्सप्रेस के एक पुराने सुविधा उपयोग करने का विकल्प है req.flash। एक्सप्रेस के नए संस्करणों में ऐसा करने से आपको दूसरे पुस्तकालय का उपयोग करने की आवश्यकता होगी। अनिवार्य रूप से यह आपको वैरिएबल सेट करने की अनुमति देता है जो किसी पृष्ठ पर जाने पर अगली बार दिखाई देगा और रीसेट करेगा। यह उपयोगकर्ताओं को त्रुटियों को दिखाने के लिए आसान है, लेकिन फिर से इसे डिफ़ॉल्ट रूप से हटा दिया गया है। EDIT: एक पुस्तकालय मिला जो इस कार्यक्षमता को जोड़ता है।

उम्मीद है कि यह आपको एक सामान्य विचार देगा कि एक्सप्रेस एप्लिकेशन में आस-पास की जानकारी कैसे पास करें।


6
प्रश्न संदर्भ को पारित करने के लिए वास्तव में ठीक नहीं लगते हैं, क्योंकि यह एक लंबे पैराग्राफ जितना बड़ा हो सकता है, या इससे भी अधिक हो सकता है। सत्रों के लिए, यह काम कर सकता है। लेकिन यह वास्तव में सही नहीं लगता है, क्योंकि यह सत्र का सही उद्देश्य नहीं लगता है ...
एनरिक मोरेनो टेंट

@ डबगर उफ़, एहसास नहीं था कि आपने सवाल पूछा था। यदि आप querystring के माध्यम से उपयोगकर्ता को बहुत अधिक जानकारी पास करने के बारे में चिंतित हैं, तो सत्यापन डेटा को किसी DB में संग्रहीत करना बेहतर होगा और तब क्वेरी कर सकता है जब आप मुख्य /मार्ग से टकराते हैं। एक अन्य विकल्प AJAX के माध्यम से पोस्ट रूट को कॉल करना है और परिणामी डेटा को स्थानीयस्टोर या कुछ इसी तरह स्टोर करना है।
अल्बर्टबेलबेल

13
अच्छा जवाब, लेकिन मुझे लगता है कि सत्र क्वेरी स्ट्रिंग की तुलना में बेहतर दृष्टिकोण है - URL में सामान को उजागर न करें!
user2562923

2
@ user2562923 मैं मानता हूं, सत्र या POST आसपास संदर्भ के लिए GETs से बेहतर हैं। जवाब बहुत अस्पष्ट था इसलिए मुझे यकीन नहीं था कि पूछने वाला किस तरह की जानकारी से गुजर रहा था।
AlbertEngelB

नोड जेएस में 2 कोर मॉड्यूल हैं जो क्वेरी स्ट्रिंग उत्पन्न करते हैं
फरीद अलनामृती

42

सबसे आसान तरीका है कि मैंने रूटहैंडलर के बीच डेटा पास करने के लिए next()रीडायरेक्ट या सत्रों के साथ गड़बड़ करने की कोई आवश्यकता नहीं है। वैकल्पिक रूप से आप homeCtrl(req,res)इसके बजाय सिर्फ अपने फोन कर सकते हैं next()और बस पास reqऔरres

var express  = require('express');
var jade     = require('jade');
var http     = require("http");


var app    = express();
var server = http.createServer(app);

/////////////
// Routing //
/////////////

// Move route middleware into named
// functions
function homeCtrl(req, res) {

    // Prepare the context
    var context = req.dataProcessed;
    res.render('home.jade', context);
}

function categoryCtrl(req, res, next) {

    // Process the data received in req.body
    // instead of res.redirect('/');
    req.dataProcessed = somethingYouDid;
    return next();
    // optionally - Same effect
    // accept no need to define homeCtrl
    // as the last piece of middleware
    // return homeCtrl(req, res, next);
}

app.get('/', homeCtrl);

app.post('/category', categoryCtrl, homeCtrl);

4
बडी, मुझे यह जवाब पसंद है। वहाँ एक छेद से बाहर निकलने में मेरी मदद की - हालाँकि मुझे वास्तव में और अधिक पढ़ने की ज़रूरत है क्योंकि मेरी आंत मेरे पास आने और तर्क के रूप में आगे () के लिए बहस करने के लिए रो रही थी।
जॉनरेड

1
बहुत अच्छा और रूढ़िवादी जवाब! अन्य उत्तरों की तुलना में बहुत आसान और बहुत अधिक सुरक्षित।
ट्राइफॉरेसी

2
यह दृष्टिकोण साफ-सुथरा प्रतीत होता है, लेकिन मुझे यकीन नहीं है कि यह नवीनतम मार्ग में पता पट्टी को छोड़ देगा या यदि यह समाप्त हो जाएगा/
डैनियलो ५१५

1
@ डैनियलो 515 यह दुर्भाग्य से / श्रेणियों पर समाप्त हो जाएगा, इसलिए यह वास्तव में केवल दृश्य को सीधे / श्रेणियों में प्रस्तुत करने के समान है ...
मैनुअल ग्राफ

2
मैं सहमत नहीं हूं कि आप केवल राउटर का उपयोग एक सेवा के रूप में कर रहे हैं जो कि आस्थगित दृश्य को प्रस्तुत करने के लिए है जो URL को छोड़ देगा क्योंकि यह आपके कोड को इस तरह से संरचना करना बुरा है, अगले का उद्देश्य अगले मिडलवेयर पर जा रहा है और हम आमतौर पर राउटर लॉजिक से हमारे व्यापार तर्क को अलग करें
फरीद अलमृती

9

मुझे एक और समाधान खोजना था क्योंकि प्रदान किए गए समाधानों में से कोई भी वास्तव में मेरी आवश्यकताओं को पूरा नहीं करता था, निम्नलिखित कारणों से:

  • क्वेरी स्ट्रिंग : आप क्वेरी स्ट्रिंग का उपयोग नहीं करना चाहते हैं क्योंकि URL आपके उपयोगकर्ताओं द्वारा साझा किए जा सकते हैं, और कभी-कभी क्वेरी पैरामीटर किसी भिन्न उपयोगकर्ता के लिए कोई मतलब नहीं रखते हैं। उदाहरण के लिए, एक त्रुटि जैसे ?error=sessionExpiredदुर्घटना से किसी अन्य उपयोगकर्ता को कभी भी प्रदर्शित नहीं किया जाना चाहिए।

  • req.session : आप इसका उपयोग नहीं करना चाहते हैं req.sessionक्योंकि आपको इसके लिए एक्सप्रेस-सत्र निर्भरता की आवश्यकता है , जिसमें एक सत्र स्टोर (जैसे MongoDB) स्थापित करना शामिल है, जिसकी आपको आवश्यकता नहीं हो सकती है, या शायद आप पहले से ही एक कस्टम का उपयोग कर रहे हैं सत्र की दुकान समाधान।

  • अगला () : आप इसका उपयोग नहीं करना चाहते next()या कर सकते हैं next("router")क्योंकि यह मूल URL के तहत अनिवार्य रूप से आपके नए पृष्ठ को प्रस्तुत करता है, यह वास्तव में नए URL पर पुनर्निर्देशित नहीं है, आगे / फिर से लिखना जैसा है, जो स्वीकार्य नहीं हो सकता है।

तो यह मेरा चौथा समाधान है जो पिछले मुद्दों में से किसी से ग्रस्त नहीं है। मूल रूप से इसमें एक अस्थायी कुकी का उपयोग करना शामिल है, जिसके लिए आपको पहले कुकी-पार्सर स्थापित करना होगा । जाहिर है इसका मतलब है कि यह केवल वहीं काम करेगा जहां कुकीज़ सक्षम हैं, और सीमित मात्रा में डेटा के साथ।

कार्यान्वयन उदाहरण:

var cookieParser = require("cookie-parser");

app.use(cookieParser());

app.get("/", function(req, res) {
    var context = req.cookies["context"];
    res.clearCookie("context", { httpOnly: true });
    res.render("home.jade", context); // Here context is just a string, you will have to provide a valid context for your template engine
});

app.post("/category", function(req, res) {
    res.cookie("context", "myContext", { httpOnly: true });
    res.redirect("/");
}

इसके लिए किसी सत्र स्टोर की आवश्यकता नहीं है express-session। एक डेटाबेस सिर्फ सत्रों को सर्वर रीस्टार्ट के लिए जारी रखता है।
माइक 'पोमैक्स' कामेरमेंस

6

app.set और app.get का उपयोग करें

डेटा सेट करना

router.get(
  "/facebook/callback",
  passport.authenticate("facebook"),
  (req, res) => {
    req.app.set('user', res.req.user)
    return res.redirect("/sign");
  }
);

डेटा प्राप्त करना

router.get("/sign", (req, res) => {
  console.log('sign', req.app.get('user'))
});

2
इसे लागू करने के लिए बुरा विचार। यह सभी उपयोगकर्ता को प्रभावित कर सकता है सभी req.app सभी उपयोगकर्ताओं के लिए समान है। हम इसके बजाय एक्सप्रेस-सत्र का उपयोग कर सकते हैं ।
उज्जल दास

5

यहाँ मैं किसी भी अन्य निर्भरता, बस नोड और एक्सप्रेस का उपयोग किए बिना सुझाव देता हूं, app.locals का उपयोग करें, यहां एक उदाहरण है:

    app.get("/", function(req, res) {
        var context = req.app.locals.specialContext;
        req.app.locals.specialContext = null;
        res.render("home.jade", context); 
        // or if you are using ejs
        res.render("home", {context: context}); 
    });

    function middleware(req, res, next) {
        req.app.locals.specialContext = * your context goes here *
        res.redirect("/");
    }

2
मुझे ऐसा लगता है कि यह एक बुरा विचार है क्योंकि req.app.locals सभी उपयोगकर्ताओं को प्रभावित करता है, न कि केवल एक जिसने अनुरोध किया है। सुनिश्चित करें कि आप उपयोगकर्ता को पास करते ही डेटा को साफ़ कर देंगे, लेकिन मुझे लगता है कि आपके पास अभी भी यह विवादित है और समय-समय पर गलत जानकारी दिखा रहा है। और अगर आपको इसे साफ करना है, तो आप इसे सत्र के बजाय स्टोर कर सकते हैं।
स्टेकर्स

1
वास्तव में यह केवल "अद्वितीय" उपयोगकर्ताओं द्वारा भेजे गए अनुरोध को प्रभावित करेगा, भले ही 2 या अधिक उपयोगकर्ता "समान समय" पर अनुरोध भेजें, प्रत्येक उपयोगकर्ता का अपना अनुरोध ऑब्जेक्ट और उसके स्थानीय ऑब्जेक्ट होगा, इस तरह यह पूरी तरह से सुरक्षित है उपयोग
हुसैन डिमसी

req एक अद्वितीय उपयोगकर्ता के लिए है, लेकिन req.app सभी उपयोगकर्ताओं के लिए है।
ZeroCho

संदेश भेजने के लिए एक्सप्रेस-सत्र का उपयोग करें
ujjal das

3

आप कुंजी / मान युग्म डेटा के छोटे बिट्स क्वेरी स्ट्रिंग के माध्यम से पास कर सकते हैं:

res.redirect('/?error=denied');

और होम पेज पर जावास्क्रिप्ट उस तक पहुँच सकते हैं और उसके अनुसार अपने व्यवहार को समायोजित कर सकते हैं।

ध्यान दें कि यदि आपको /categoryब्राउज़र एड्रेस बार में URL के रूप में रहने में कोई आपत्ति नहीं है , तो आप रीडायरेक्ट करने के बजाय सीधे रेंडर कर सकते हैं। IMHO कई बार लोग रीडायरेक्ट का उपयोग करते हैं क्योंकि पुराने वेब फ्रेमवर्क सीधे कठिन प्रतिक्रिया देते हैं, लेकिन यह एक्सप्रेस में आसान है:

app.post('/category', function(req, res) {

  // Process the data received in req.body

  res.render('home.jade', {error: 'denied'});
});

जैसा कि @ Dropped.on.Caprica ने टिप्पणी की, AJAX का उपयोग करने से URL की चिंता समाप्त हो जाती है।


जैसा कि मैंने एक अन्य उत्तर में कहा, क्वेरी स्ट्रिंग्स अच्छे नहीं लगते हैं, क्योंकि मुझे अभी तक नहीं पता है कि मैं कितना बड़ा डेटा पास करना चाहता हूं। आपका अन्य समाधान मेरे द्वारा पाया गया अधिक जन्मजात है, लेकिन यह अभी भी उसी URL को रखने के मेरे इरादे को तोड़ता है।
एनरिक मोरेनो टेंट

@Dbugger संभवतः AJAX पोस्ट का उपयोग करें?
अल्बर्टबेलबेल

1

हम आवश्यक डेटा भेजने के लिए एक्सप्रेस-सत्र का उपयोग कर सकते हैं

जब आप ऐप को इनिशियलाइज़ करते हैं

const express = require('express');
const app = express();
const session = require('express-session');
app.use(session({secret: 'mySecret', resave: false, saveUninitialized: false}));

इसलिए पुनर्निर्देशन से पहले सिर्फ सत्र के संदर्भ को बचाएं

app.post('/category', function(req, res) {
    // add your context here 
req.session.context ='your context here' ;
    res.redirect('/');
});

अब आप सत्र के लिए कहीं भी संदर्भ प्राप्त कर सकते हैं। यह सिर्फ req.session.context द्वारा प्राप्त कर सकते हैं

app.get('/', function(req, res) {

    // So prepare the context
var context=req.session.context;
    res.render('home.jade', context);
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.