node.js 传递一些上下文时如何在expressjs中重定向?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19035373/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I redirect in expressjs while passing some context?
提问by Enrique Moreno Tent
I am using express to make a web app in node.js. This is a simplification of what I have:
我正在使用 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('/');
});
My problem is the following:
我的问题如下:
If I find that the data sent in /categorydoesn't validate, I would like pass some additional context to the /page. How could I do this? Redirect doesn't seem to allow any kind of extra parameter.
如果我发现发送的数据/category没有经过验证,我想向/页面传递一些额外的上下文。我怎么能这样做?重定向似乎不允许任何类型的额外参数。
回答by AlbertEngelB
There are a few ways of passing data around to different routes. The most correct answer is, of course, query strings. You'll need to ensure that the values are properly encodeURIComponentand decodeURIComponent.
有几种方法可以将数据传递到不同的路由。最正确的答案当然是查询字符串。您需要确保这些值是正确的encodeURIComponent和decodeURIComponent。
app.get('/category', function(req, res) {
var string = encodeURIComponent('something that would break');
res.redirect('/?valid=' + string);
});
You can snag that in your other route by getting the parameters sent by using req.query.
您可以通过使用req.query.
app.get('/', function(req, res) {
var passedVariable = req.query.valid;
// Do something with variable
});
For more dynamic way you can use the urlcore module to generate the query string for you:
对于更动态的方式,您可以使用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"
}
}));
});
So if you want to redirect all req query string variables you can simply do
所以如果你想重定向所有 req 查询字符串变量,你可以简单地做
res.redirect(url.format({
pathname:"/",
query:req.query,
});
});
And if you are using Node >= 7.x you can also use the querystringcore module
如果你使用 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);
});
Another way of doing it is by setting something up in the session. You can read how to set it up here, but to set and access variables is something like this:
另一种方法是在会话中设置一些东西。 你可以在这里阅读如何设置它,但是设置和访问变量是这样的:
app.get('/category', function(req, res) {
req.session.valid = true;
res.redirect('/');
});
And later on after the redirect...
后来在重定向之后......
app.get('/', function(req, res) {
var passedVariable = req.session.valid;
req.session.valid = null; // resets session variable
// Do something
});
There is also the option of using an old feature of Express, req.flash. Doing so in newer versions of Express will require you to use another library. Essentially it allows you to set up variables that will show up and reset the next time you go to a page. It's handy for showing errors to users, but again it's been removed by default. EDIT: Found a library that adds this functionality.
还可以选择使用 Express 的旧功能,req.flash. 在较新版本的 Express 中这样做将需要您使用另一个库。本质上,它允许您设置变量,这些变量将在您下次访问页面时显示和重置。向用户显示错误很方便,但默认情况下它已被删除。编辑:找到一个添加此功能的库。
Hopefully that will give you a general idea how to pass information around in an Express application.
希望这能让您大致了解如何在 Express 应用程序中传递信息。
回答by jqualls
The easiest way I have found to pass data between routeHandlers to use next()no need to mess with redirect or sessions.
Optionally you could just call your homeCtrl(req,res)instead of next()and just pass the reqand res
我发现最简单的方法是在 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);
回答by cprcrack
I had to find another solution because none of the provided solutions actually met my requirements, for the following reasons:
我不得不寻找另一个解决方案,因为提供的解决方案都没有真正满足我的要求,原因如下:
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=sessionExpiredshould never be displayed to another user by accident.req.session: You may not want to use
req.sessionbecause you need the express-sessiondependency 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()ornext("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.
查询字符串:您可能不想使用查询字符串,因为 URL 可能由您的用户共享,有时查询参数对不同的用户没有意义。例如,
?error=sessionExpired不应向其他用户意外显示诸如此类的错误。req.session:您可能不想使用,
req.session因为您需要为此使用express-session依赖项,其中包括设置会话存储(例如 MongoDB),您可能根本不需要,或者您可能已经在使用自定义会话存储解决方案。next():您可能不想使用,
next()或者next("router")因为这实际上只是在原始 URL 下呈现您的新页面,它并不是真正重定向到新 URL,更像是转发/重写,这可能是不可接受的。
So this is my fourth solution that doesn't suffer from any of the previous issues. Basically it involves using a temporary cookie, for which you will have to first install cookie-parser. Obviously this means it will only work where cookies are enabled, and with a limited amount of data.
所以这是我的第四个解决方案,它不会遇到任何以前的问题。基本上它涉及使用临时 cookie,为此您必须首先安装cookie-parser。显然,这意味着它只能在启用 cookie 且数据量有限的情况下工作。
Implementation example:
实现示例:
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("/");
}
回答by UA_
use app.set & app.get
使用 app.set 和 app.get
Setting data
设置数据
router.get(
"/facebook/callback",
passport.authenticate("facebook"),
(req, res) => {
req.app.set('user', res.req.user)
return res.redirect("/sign");
}
);
Getting data
获取数据
router.get("/sign", (req, res) => {
console.log('sign', req.app.get('user'))
});
回答by Hussein Dimessi
Here s what I suggest without using any other dependency , just node and express, use app.locals, here s an example :
这是我的建议,不使用任何其他依赖项,仅使用 node 和 express,使用 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("/");
}
回答by Peter Lyons
You can pass small bits of key/value pair data via the query string:
您可以通过查询字符串传递少量的键/值对数据:
res.redirect('/?error=denied');
And javascript on the home page can access that and adjust its behavior accordingly.
主页上的 javascript 可以访问它并相应地调整其行为。
Note that if you don't mind /categorystaying as the URL in the browser address bar, you can just render directly instead of redirecting. IMHO many times people use redirects because older web frameworks made directly responding difficult, but it's easy in express:
请注意,如果您不介意/category留在浏览器地址栏中的 URL,您可以直接渲染而不是重定向。恕我直言,人们多次使用重定向是因为旧的 Web 框架使直接响应变得困难,但在 express 中很容易:
app.post('/category', function(req, res) {
// Process the data received in req.body
res.render('home.jade', {error: 'denied'});
});
As @Dropped.on.Caprica commented, using AJAX eliminates the URL changing concern.
正如@Dropped.on.Caprica 评论的那样,使用 AJAX 消除了 URL 更改问题。
回答by ujjal das
we can use express-sessionto send the required data
我们可以使用express-session发送所需的数据
when you initialise the app
当您初始化应用程序时
const express = require('express');
const app = express();
const session = require('express-session');
app.use(session({secret: 'mySecret', resave: false, saveUninitialized: false}));
so before redirection just save the context for the session
所以在重定向之前只需保存会话的上下文
app.post('/category', function(req, res) {
// add your context here
req.session.context ='your context here' ;
res.redirect('/');
});
Now you can get the context anywhere for the session. it can get just by req.session.context
现在您可以在任何地方获取会话的上下文。它可以通过req.session.context 获取
app.get('/', function(req, res) {
// So prepare the context
var context=req.session.context;
res.render('home.jade', context);
});

