ExpressJS res.render()错误(JSON.stringify无法在循环引用上工作)
这里有什么问题?
res.render('/somepage', {user:req.session.user})
它导致
将圆形结构转换为JSON
错误(导致会话元素具有循环的用户引用)。
exports.home = function (req, res) { var entityFactory = new require('../lib/entity-factory.js').EntityFactory(); entityFactory.get_job_task_lists({ callback : function (err, job_task_lists) { res.render('home.jade', { locals:{ title: 'Logged in.', user:req.session.user, // does not work job_task_lists:job_task_lists || [] } }); } }); };
exports.home = function (req, res) { var entityFactory = new require('../lib/entity-factory.js').EntityFactory(); entityFactory.get_job_task_lists({ callback : function (err, job_task_lists) { res.render('home.jade', { locals:{ title: 'Logged in.', user:req.session.user, // does not work job_task_lists:job_task_lists || [] } }); } }); };
我在node_modules/express/node_modules/connect/lib/middleware/session/memory.js
添加了一些日志logging
MemoryStore.prototype.set = function(sid,sess,fn){ var self = this; process.nextTick(函数(){ 的console.log(SESS); //这是列出的输出 self.sessions [sid] = JSON.stringify(sess); ...
就结构而言,这是我期望会议的样子:
{lastAccess:1330979534026, 曲奇饼: {path:'/', httpOnly:true, _expires:星期二,06三月2012 00:32:14 GMT, originalMaxAge:14399999}, 用户://这是我添加到会话中的对象 {id:1, 用户名:'admin', 密码:'8e3f8d3a98481a9073d2ab69f93ce73b', creation_date:Mon,05 Mar 2012 18:08:55 GMT}}
但是,我发现:
{lastAccess:1330979534079,//新的会话 曲奇饼: {path:'/', httpOnly:true, _expires:星期二,06三月2012 00:32:14 GMT, originalMaxAge:14399999}, 用户:/ /但这里又是,除了现在是一个混搭, //包含它不应该拥有的成员,比如本地人, //除了前四个属性外, {id:1, 用户名:'admin', 密码:'8e3f8d3a98481a9073d2ab69f93ce73b', creation_date:'2012-03-05T18:08:55.701Z', 当地人: {title:'login。', 用户:[Circular],//现在是循环的 job_task_lists:[Object]}, 标题:“已login”, 用户:[圆形], job_task_lists:[[Object],[Object],[Object],getById:[Function]], 尝试:['/home/dan/development/aqp/views/home.jade'], 范围: {}, parentView:undefined, root:'/ home / dan / development / aqp / views', defaultEngine:“玉”, 设置: {env:'发展', 提示:真实的, views:'/ home / dan / development / aqp / views', '视图引擎':'玉'}, 应用: {stack:[Object], 连线:6, allowHalfOpen:true, _handle:[Object], _events:[Object], httpAllowHalfOpen:false, caching:[对象], 设置:[对象], redirect:{}, isCallbacks:{}, _locals:[对象], dynamicViewHelpers:{}, errorHandlers:[], 路线:'/', 路线:[对象], 路由器:[Getter], __usedRouter:true}, 部分:[function], 提示:是的, 文件名:'/home/dan/development/aqp/views/home.jade', 布局:假, isPartial:true}} Node.js的:201 扔e; // process.nextTick错误,或第一次打勾时发生“错误”事件 ^ TypeError:将圆形结构转换为JSON 在Object.stringify(native) 在Array.0(/home/dan/development/aqp/node_modules/express/node_modules/connect/lib/middleware/session/memory.js:77:31) 在EventEmitter._tickCallback(node.js:192:40)
看看用户对象是如何嵌套的?
- 请注意,这次我没有用“本地人”显式地发送值,但是它最终在一个(这是循环引用的来源。
它看起来像会话正在被用来传递对象到视图。
这是我唯一的中间件(只能从会话中读取):
函数requiresAuthentication(req,res,next){ if(req.session.user){ 下一个(); } else { 下一个(新错误('未经授权,请使用有效帐号login')) } }
而我唯一修改req.session的时间就是这条路线:
app.post('/ home',function(req,res,next){ var auth = require('./ lib / authentication'); auth.authenticate_user(req.body.user,function(user){ 如果(用户){ req.session.user = user; 的console.log( '证实的'); res.redirect(req.body.redir ||'/ home'); //下一个(); } else { console.log('not authenticated'); res.render('logins / new.jade',{title:'login失败',redir:''}) } }); });
我的应用程序中没有其他的东西,因为它还很年轻。 我知道我自己并没有在任何地方打破这个会议。 我检查了。
我做了一些更多的testing,看来这只是一个问题,当我尝试在页面上使用本地variables。 例如,这里是我的看法home.jade
DIV(数据angular色=“页面”) DIV(数据angular色=“报头”) a(href ='/ logout',data-icon ='delete',data-ajax =“false”)注销 h1 =标题 a(href ='/ account',data-icon ='info',data-ajax =“false”)帐号 !=部分('用户',用户) job_task_lists中的每个jtl div(id = jtl.name,class ='draggable_item',style ='border:2px solid black;') #{jtl.name} - #{jtl.description} 一个(数据图标=“加”) DIV(数据angular色=“页脚”) h3页脚 脚本(SRC = “/ Javascriptangular/ home.js”)
如果我注释掉部分用户,它呈现,否则我得到这个Converting circular structure to JSON
问题的Converting circular structure to JSON
。
更新所以在连接eclipse和v8debugging器之后,我已经逐步完成代码,并且知道会话和用户对象的混搭发生在哪里,
在node_modules/connect/lib/middleware/session/session.js
utils.union最终将用户对象的成员混合到会话中,引起循环引用。 我只是不知道为什么(诚然可能是我的代码)
这是会话数据在视图中被修改的问题。
经过大量的挖掘,我发现这是一个在2.5.8处理partials的bug。 我提交了一个问题 ,随后给出了一个补丁 。 (以防任何人在未来的date需要这个信息),因为npm仍在服务于Express 2.5.8 AFAIK。
感谢您的帮助@freakish和@Ryan