我正在使用express在node.js中制作一个web应用程序。这是对我所拥有的东西的简化:
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中发送的数据不有效,我想向/页传递一些额外的上下文。我怎么能这样做呢?重定向似乎不允许任何类型的额外参数。
我们可以使用express-session发送所需的数据
当你初始化应用程序
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('/');
});
现在您可以在会话的任何地方获取上下文。它可以通过request。session。context获得
app.get('/', function(req, res) {
// So prepare the context
var context=req.session.context;
res.render('home.jade', context);
});
使用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'))
});
下面是我的建议,不使用任何其他依赖,只是节点和表达式,使用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("/");
}
我们可以使用express-session发送所需的数据
当你初始化应用程序
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('/');
});
现在您可以在会话的任何地方获取上下文。它可以通过request。session。context获得
app.get('/', function(req, res) {
// So prepare the context
var context=req.session.context;
res.render('home.jade', context);
});
我不得不寻找另一个解决方案,因为所提供的解决方案实际上没有一个满足我的要求,原因如下:
Query strings: You may not want to use query strings because the URLs could be shared by your users, and sometimes the query parameters do not make sense for a different user. For example, an error such as ?error=sessionExpired should never be displayed to another user by accident.
req.session: You may not want to use req.session because you need the express-session dependency for this, which includes setting up a session store (such as MongoDB), which you may not need at all, or maybe you are already using a custom session store solution.
next(): You may not want to use next() or next("router") because this essentially just renders your new page under the original URL, it's not really a redirect to the new URL, more like a forward/rewrite, which may not be acceptable.
所以这是我的第四个解决方案,没有任何前面的问题。基本上,它涉及到使用一个临时cookie,为此你必须首先安装cookie-parser。显然,这意味着它只能在启用cookie的情况下工作,并且数据量有限。
实现的例子:
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("/");
}
我发现的最简单的方法是在routeHandlers之间传递数据来使用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);