我正在使用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
中发送的数据未验证,我想将一些额外的上下文传递给/
页面。我怎么能这样做?重定向似乎不允许任何类型的额外参数。
答案 0 :(得分:295)
有几种方法可以将数据传递到不同的路径。当然,最正确的答案是查询字符串。您需要确保值正确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"
}
}));
});
因此,如果您想重定向所有req查询字符串变量,只需执行
即可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);
});
另一种方法是在会话中设置一些东西。 You can read how to set it up here,但设置和访问变量是这样的:
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
});
还可以选择使用Express的旧功能req.flash
。在较新版本的Express中执行此操作将要求您使用其他库。从本质上讲,它允许您设置将在下次进入页面时显示和重置的变量。向用户显示错误很方便,但默认情况下它已被删除。编辑:Found a library that adds this functionality.
希望这能让您大致了解如何在Express应用程序中传递信息。
答案 1 :(得分:34)
我发现在routeHandler之间传递数据以使用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);
答案 2 :(得分:4)
由于以下原因,所提供的解决方案均未真正满足我的要求,因此我不得不找到另一种解决方案:
查询字符串:您可能不希望使用查询字符串,因为URL可以由您的用户共享,有时查询参数对其他用户没有意义。例如,诸如?error=sessionExpired
之类的错误永远不要偶然显示给其他用户。
请求会话:您可能不想使用req.session
,因为为此需要express-session依赖项,包括建立会话存储区(例如例如MongoDB),您可能根本不需要它,或者您已经在使用自定义会话存储解决方案。
next():您可能不想使用next()
或next("router")
,因为这实际上只是将新页面呈现在原始URL下,并不是真的重定向到新URL,更像是转发/重写,这可能是不可接受的。
因此,这是我的第四个解决方案,没有任何前述问题。基本上,它涉及使用临时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("/");
}
答案 3 :(得分:3)
我们可以使用 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('/');
});
现在,您可以在会话的任何位置获取上下文。它可以通过 req.session.context
获得app.get('/', function(req, res) {
// So prepare the context
var context=req.session.context;
res.render('home.jade', context);
});
答案 4 :(得分:2)
您可以通过查询字符串传递少量键/值对数据:
res.redirect('/?error=denied');
主页上的javascript可以访问它并相应地调整其行为。
请注意,如果您不介意/category
保留在浏览器地址栏中的URL,则可以直接渲染而不是重定向。恕我直言,很多时候人们使用重定向,因为较旧的Web框架使得直接响应变得困难,但它很容易表达:
app.post('/category', function(req, res) {
// Process the data received in req.body
res.render('home.jade', {error: 'denied'});
});
正如@ Dropped.on.Caprica评论的那样,使用AJAX可以消除URL变化问题。
答案 5 :(得分:2)
这是我建议不使用任何其他依赖项的内容,仅使用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("/");
}
答案 6 :(得分:1)
使用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'))
});
答案 7 :(得分:0)
解决方案之一是主体解析器中间件,并将数据作为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 });
});
您可以在通过此'/'
路径访问的页面中使用此数据对象
答案 8 :(得分:0)
我使用了一种非常简单但有效的技术 在我的 app.js(我的入口点) 我定义了一个像
这样的变量let authUser = {};
然后我从我的路线页面分配给它(比如成功登录后)
authUser = matchedUser
这可能不是最好的方法,但它符合我的需求。
答案 9 :(得分:-2)
app.get('/category', function(req, res) {
var string = query
res.redirect('/?valid=' + string);
});
在ejs中,您可以直接使用有效:
<% var k = valid %>