J'utilise express pour créer une application Web dans node.js. Ceci est une simplification de ce que j'ai:
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('/');
});
Mon problème est le suivant:
Si je constate que les données envoyées dans /category
ne sont pas validées, j'aimerais passer un contexte supplémentaire à la page /
. Comment pourrais-je faire ça? La redirection ne semble autoriser aucun type de paramètre supplémentaire.
Il existe quelques moyens de transmettre des données à différents itinéraires. La réponse la plus correcte est, bien sûr, les chaînes de requête. Vous devez vous assurer que les valeurs sont correctement encodeURIComponent et decodeURIComponent .
app.get('/category', function(req, res) {
var string = encodeURIComponent('something that would break');
res.redirect('/?valid=' + string);
});
Vous pouvez accrocher cela dans votre autre route en récupérant les paramètres envoyés en utilisant req.query
.
app.get('/', function(req, res) {
var passedVariable = req.query.valid;
// Do something with variable
});
Pour plus dynamique, vous pouvez utiliser le module url
core pour générer la chaîne de requête pour vous:
const url = require('url');
app.get('/category', function(req, res) {
res.redirect(url.format({
pathname:"/",
query: {
"a": 1,
"b": 2,
"valid":"your string here"
}
}));
});
Donc, si vous voulez rediriger toutes les variables de chaîne de requête req, vous pouvez simplement le faire
res.redirect(url.format({
pathname:"/",
query:req.query,
});
});
Et si vous utilisez Node> = 7.x, vous pouvez également utiliser le module querystring
core
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);
});
Une autre façon de le faire est d’organiser quelque chose dans la session. Vous pouvez lire comment le configurer ici , mais définir et accéder aux variables ressemble à ceci:
app.get('/category', function(req, res) {
req.session.valid = true;
res.redirect('/');
});
Et plus tard, après la redirection ...
app.get('/', function(req, res) {
var passedVariable = req.session.valid;
req.session.valid = null; // resets session variable
// Do something
});
Il existe également la possibilité d'utiliser une ancienne fonctionnalité d'Express, req.flash
. Dans les nouvelles versions d'Express, vous devrez utiliser une autre bibliothèque. Essentiellement, cela vous permet de configurer des variables qui apparaîtront et se réinitialiseront la prochaine fois que vous irez sur une page. C'est pratique pour montrer les erreurs aux utilisateurs, mais encore une fois, il a été supprimé par défaut. EDIT: Trouvé une bibliothèque qui ajoute cette fonctionnalité.
J'espère que cela vous donnera une idée générale de la manière de transmettre des informations dans une application Express.
Le moyen le plus simple que j'ai trouvé pour transmettre des données entre routeHandlers consiste à utiliser next()
sans avoir à manipuler les redirections ni les sessions . Vous pouvez éventuellement appeler votre homeCtrl(req,res)
au lieu de next()
et simplement passer les req
et 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);
Voici ce que je suggère sans utiliser aucune autre dépendance, juste node et express, utilisez app.locals, voici un exemple:
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("/");
}
Vous pouvez transmettre de petits bits de données de paire clé/valeur via la chaîne de requête:
res.redirect('/?error=denied');
Et javascript sur la page d'accueil peut accéder à cela et ajuster son comportement en conséquence.
Notez que si /category
ne craint pas de rester en tant qu'URL dans la barre d'adresse du navigateur, vous pouvez simplement effectuer le rendu directement au lieu de la redirection. À mon humble avis, les gens utilisent souvent des redirections parce que les anciens frameworks Web rendaient la réponse directe difficile, mais c'est facile dans express:
app.post('/category', function(req, res) {
// Process the data received in req.body
res.render('home.jade', {error: 'denied'});
});
Comme @ Dropped.on.Caprica a commenté, l'utilisation de AJAX élimine le problème de modification de l'URL.
J'ai dû trouver une autre solution car aucune des solutions fournies ne répondait réellement à mes exigences, pour les raisons suivantes:
Chaînes de requête: vous souhaiterez peut-être ne pas utiliser de chaînes de requête car les URL pourraient être partagées par vos utilisateurs. Par conséquent, les paramètres de requête n'ont parfois aucun sens pour un utilisateur différent. Par exemple, une erreur telle que ?error=sessionExpired
ne doit jamais être affichée par accident à un autre utilisateur.
req.session: vous voudrez peut-être ne pas utiliser req.session
car vous avez besoin de la dépendance express-session , qui inclut la configuration d'un magasin de sessions (tel que MongoDB), dont vous n'avez peut-être pas besoin , ou peut-être utilisez-vous déjà une solution de magasin de session personnalisée.
next (): Vous ne voudrez peut-être pas utiliser next()
ou next("router")
car cela ne fait que rendre votre nouvelle page sous l'URL d'origine. être acceptable.
C'est donc ma quatrième solution qui ne souffre d'aucun des problèmes précédents. Fondamentalement, cela implique l’utilisation d’un cookie temporaire, pour lequel vous devrez d’abord installer cookie-parser . Évidemment, cela signifie que cela ne fonctionnera que si les cookies sont activés et avec une quantité de données limitée.
Exemple d'implémentation:
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("/");
}
L'une des solutions consiste à utiliser le middleware d'analyse syntaxique du corps et à transmettre les données sous forme d'objet JSON.
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 });
});
Vous pouvez utiliser cet objet de données dans la page accessible via ce chemin '/'
.