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