it-swarm.com.de

Wie kann ich in expressjs umleiten, während ich einen Kontext übergeben?

Ich verwende express, um eine Web-App in node.js zu erstellen. Dies ist eine Vereinfachung dessen, was ich habe:

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('/');
});

Mein Problem ist folgendes:

Wenn ich feststelle, dass die in /category gesendeten Daten nicht gültig sind, möchte ich der Seite / einen zusätzlichen Kontext übergeben. Wie kann ich das machen? Die Umleitung scheint keine zusätzlichen Parameter zuzulassen.

184

Es gibt verschiedene Möglichkeiten, Daten auf verschiedene Routen zu übertragen. Die richtigste Antwort sind natürlich Abfragezeichenfolgen. Sie müssen sicherstellen, dass die Werte richtig sind encodeURIComponent und decodeURIComponent .

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

Sie können dies auf Ihrer anderen Route feststellen, indem Sie die Parameter mit req.query senden.

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

Für eine dynamischere Art und Weise können Sie mit dem url - Modul die Abfragezeichenfolge für Sie generieren:

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

Wenn Sie also alle req-Abfragezeichenfolgenvariablen umleiten möchten, können Sie dies einfach tun 

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

Wenn Sie Node> = 7.x verwenden, können Sie auch das querystring core-Modul verwenden

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

Eine andere Möglichkeit besteht darin, etwas in der Sitzung einzurichten. Sie können hier nachlesen, wie Sie es einrichten , aber Variablen setzen und aufrufen ist etwa so:

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

Und später nach der Weiterleitung ...

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

Es besteht auch die Möglichkeit, eine alte Express-Funktion, req.flash, zu verwenden. In neueren Versionen von Express müssen Sie eine andere Bibliothek verwenden. Im Wesentlichen können Sie Variablen einrichten, die beim nächsten Aufruf einer Seite angezeigt und zurückgesetzt werden. Es ist praktisch, um den Benutzern Fehler anzuzeigen, wurde aber standardmäßig wieder entfernt. EDIT: Eine Bibliothek gefunden, die diese Funktionalität hinzufügt.

Hoffentlich erhalten Sie so eine allgemeine Vorstellung davon, wie Sie Informationen in einer Express-Anwendung weitergeben.

273
AlbertEngelB

Die einfachste Methode, die ich gefunden habe, um Daten zwischen routeHandlers zu übergeben, um next() zu verwenden, ist keine Notwendigkeit, sich mit Weiterleitung oder Sitzungen zu beschäftigen. Optional können Sie einfach homeCtrl(req,res) anstelle von next() aufrufen und einfach die req und res übergeben.

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);
33
jqualls

Ich schlage Folgendes vor, ohne eine andere Abhängigkeit zu verwenden: Nur node und express. Verwenden Sie app.locals. Hier ein Beispiel:

    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
Hussein Dimessi

Sie können kleine Bits von Schlüssel/Wert-Paardaten über die Abfragezeichenfolge übergeben:

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

Und Javascript auf der Homepage kann darauf zugreifen und sein Verhalten entsprechend anpassen.

Wenn Sie nichts dagegen haben, dass /category als URL in der Adressleiste des Browsers verbleibt, können Sie nur direkt rendern, anstatt umzuleiten. IMHO verwenden Menschen häufig Weiterleitungen, weil ältere Web-Frameworks die direkte Reaktion schwierig machten, aber es lässt sich leicht ausdrücken:

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

  // Process the data received in req.body

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

Wie @ Dropped.on.Caprica kommentierte, beseitigt die Verwendung von AJAX das Problem der Änderung der URL.

2
Peter Lyons

Ich musste eine andere Lösung finden, da keine der angebotenen Lösungen meinen Anforderungen aus folgenden Gründen tatsächlich entsprach:

  • Abfragezeichenfolgen: Möglicherweise möchten Sie keine Abfragezeichenfolgen verwenden, da die URLs möglicherweise von Ihren Benutzern gemeinsam verwendet werden und die Abfrageparameter für einen anderen Benutzer nicht sinnvoll sind. Beispielsweise sollte ein Fehler wie ?error=sessionExpired niemals versehentlich einem anderen Benutzer angezeigt werden.

  • req.session: Möglicherweise möchten Sie req.session nicht verwenden, da Sie dazu die Abhängigkeit von express-session benötigen. Dazu gehört auch das Einrichten eines Sitzungsspeichers (z. B. MongoDB), den Sie möglicherweise gar nicht benötigen oder Sie verwenden bereits eine benutzerdefinierte Lösung für den Sitzungsspeicher.

  • next (): Möglicherweise möchten Sie next() oder next("router") nicht verwenden, da dies Ihre neue Seite im Wesentlichen nur unter der ursprünglichen URL darstellt. Es handelt sich nicht wirklich um eine Weiterleitung auf die neue URL, eher um ein Weiterleiten/Umschreiben akzeptabel sein.

Dies ist meine vierte Lösung, die unter keinem der vorherigen Probleme leidet. Im Wesentlichen handelt es sich dabei um ein temporäres Cookie, für das Sie zuerst cookie-parser installieren müssen. Das bedeutet natürlich, dass es nur dort funktioniert, wo Cookies aktiviert sind und nur eine begrenzte Datenmenge.

Implementierungsbeispiel:

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("/");
}
1
cprcrack

Eine der Lösungen ist die Body-Parser-Middleware, mit der die Daten als JSON-Objekt übergeben werden

var express = require('express');
var jade = require('jade');
var http = require("http");
const bodyParser = require('body-parser') //requiring body parser 


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
  //pass the data as an json object 
  res.redirect('/', { data: data });
});

Sie können dieses Datenobjekt auf der Seite verwenden, die über diesen '/'-Pfad erreicht wird

0
Hadi Mir