使用Router()参数进行快递
Express using the Router() params
假设我使用express的Router()获得了这段代码。
authRoute.param('token', function(req, res, next, token) {
User.findOne({ 'local.resetPasswordToken': req.params.token, resetPasswordExpires: { $gt: Date.now() }}, function(err, user) {
if (!user) {
req.flash('error', 'error msg here');
return res.redirect('/forgot');
}
req.user = user;
})
next();
})
authRoute.route('/reset/:token')
.get(function(req, res) {
res.render('reset', {
user: req.user
})
})
我得到这个错误:
_http_outgoing.js:346
throw new Error('Can''t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11)
如果没有Router(),它看起来就是这样:
app.get('/reset/:token', function(req, res) {
User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
if (!user) {
req.flash('error', 'Password reset token is invalid or has expired.');
return res.redirect('/forgot');
}
res.render('reset', {
user: req.user
});
});
});
Router.param端出了什么问题?我阅读了给出的错误消息,了解到当试图在已经设置的响应上设置标头时会发生这种情况。
您正在authRout.param中立即调用next()
,从而允许其他中间件在调用Mongoose回调之前,在某个时刻调用res.end()
(res.render、res.send等)。我的假设是,当允许中间件执行(前面解释过),然后在其中一个中间件已经"结束"响应后调用res.redirect('/forgot')
时,会出现此错误。
解决方案是在继续中间件链之前等待数据库响应,这只是一个异步问题。考虑以下内容:
authRoute.param('token', function(req, res, next, token) {
User.findOne({ 'local.resetPasswordToken': req.params.token, resetPasswordExpires: { $gt: Date.now() }}, function(err, user) {
// pass error to middlewares
if (err) return next(err)
// Stop the middleware chain i.e. return res.redirect
if (!user) {
req.flash('error', 'error msg here');
return res.redirect('/forgot');
}
req.user = user;
// important! call `next()` after mongo response
next()
})
})
在单个请求处理程序(后一个示例)中不会发生这种情况,因为您正确地处理了async,而不是在调用Mongoose回调之前结束http响应。
相关文章:
- 函数参数中的数据与指定变量之间的任何性能差异
- 使用Express捕获参数
- 参数变量出现ngTable指令问题
- AngularJS:我可以跳过函数参数回调吗
- 如何使用skip参数使用angular ui引导进行服务器端分页
- 要求未定义JS回调参数
- 我的jQuery插件参数没有正确启动,遇到了问题
- 获取@ResponseBody的一部分作为主干和Spring MVC控制器之间的参数
- jquery设置为使用参数运行
- Javascript”;类“;带有参数的扩展
- 为什么grunt contrib connect的中间件选项的第三个参数是未定义的
- 函数未将值作为参数传递
- 如何将参数传递到angularJs中的工厂
- JS:检查URL中的参数,然后迭代一个参数为var的函数
- 正在传递JSONP标头's数据参数到另一个文件中的AJAX请求
- MVC 3页面导航和使用javascript传递参数
- 从查询字符串参数推断出正确的数据类型
- 使用Router()参数进行快递
- 检查所有参数帆的助手 - 快递
- 铁路中的快递子域处理程序告诉我子域参数(在路线中)是控制器的原因