2012-03-05 8 views
5

¿Qué sucede aquí?ExpressJS res.render() error (JSON.stringify no puede funcionar en referencia circular)

res.render('/somepage', {user:req.session.user})

Conduce a

Converting circular structure to JSON
errores, (resultados en elemento de sesión que tiene una referencia de usuario circular.)

 

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 || [] 
         } 
      }); 
     } 
    }); 
}; 

 

I añadido algunas tala en node_modules/express/node_modules/connect/lib/middleware/session/memory.js

 
MemoryStore.prototype.set = function(sid, sess, fn){ 
    var self = this; 
    process.nextTick(function(){ 

    console.log(sess); //this is giving the output listed 

    self.sessions[sid] = JSON.stringify(sess); 
... 

Esto es lo que espero que sea la sesión, en términos de estructura:

 
{ lastAccess: 1330979534026, 
    cookie: 
    { path: '/', 
    httpOnly: true, 
    _expires: Tue, 06 Mar 2012 00:32:14 GMT, 
    originalMaxAge: 14399999 }, 
    user: // this is the object I added to the session 
    { id: 1, 
    username: 'admin', 
    password: '8e3f8d3a98481a9073d2ab69f93ce73b', 
    creation_date: Mon, 05 Mar 2012 18:08:55 GMT } } 

Pero aquí es lo que encuentro:

 
{ lastAccess: 1330979534079, // new session 
    cookie: 
    { path: '/', 
    httpOnly: true, 
    _expires: Tue, 06 Mar 2012 00:32:14 GMT, 
    originalMaxAge: 14399999 }, 
    user: // but here it is again, except now it's a mashup, 
     // containing members it shouldn't have, like locals, 
     // and, well, everything but the first 4 properties 
    { id: 1, 
    username: 'admin', 
    password: '8e3f8d3a98481a9073d2ab69f93ce73b', 
    creation_date: '2012-03-05T18:08:55.701Z', 
    locals: 
     { title: 'Logged in.', 
     user: [Circular], //and now it's circular 
     job_task_lists: [Object] }, 
    title: 'Logged in.', 
    user: [Circular], 
    job_task_lists: [ [Object], [Object], [Object], getById: [Function] ], 
    attempts: [ '/home/dan/development/aqp/views/home.jade' ], 
    scope: {}, 
    parentView: undefined, 
    root: '/home/dan/development/aqp/views', 
    defaultEngine: 'jade', 
    settings: 
     { env: 'development', 
     hints: true, 
     views: '/home/dan/development/aqp/views', 
     'view engine': 'jade' }, 
    app: 
     { stack: [Object], 
     connections: 6, 
     allowHalfOpen: true, 
     _handle: [Object], 
     _events: [Object], 
     httpAllowHalfOpen: false, 
     cache: [Object], 
     settings: [Object], 
     redirects: {}, 
     isCallbacks: {}, 
     _locals: [Object], 
     dynamicViewHelpers: {}, 
     errorHandlers: [], 
     route: '/', 
     routes: [Object], 
     router: [Getter], 
     __usedRouter: true }, 
    partial: [Function], 
    hint: true, 
    filename: '/home/dan/development/aqp/views/home.jade', 
    layout: false, 
    isPartial: true } } 

node.js:201 
     throw e; // process.nextTick error, or 'error' event on first tick 
      ^
TypeError: Converting circular structure to JSON 
    at Object.stringify (native) 
    at Array.0 (/home/dan/development/aqp/node_modules/express/node_modules/connect/lib/middleware/session/memory.js:77:31) 
    at EventEmitter._tickCallback (node.js:192:40) 

Vea cómo se anida el objeto de usuario?

  • Tenga en cuenta que esta vez no envió a los valores en forma explícita con 'locales' pero terminó en un (esa es la fuente de la referencia circular.

Parece que la sesión es . siendo utilizado para transferir objetos a la vista

Aquí es mi único middleware (sólo se lee de la sesión):

 
function requiresAuthentication(req, res, next){ 
    if (req.session.user){ 
     next(); 
    } else { 
     next(new Error('Unauthorized. Please log in with a valid account.')) 
    } 
} 

y la única vez que modificar el req.session está en esta ruta:

 
app.post('/home', function (req,res,next) { 
    var auth = require('./lib/authentication'); 
    auth.authenticate_user(req.body.user, function (user) { 
     if (user){ 
      req.session.user = user; 
      console.log('authenticated'); 
      res.redirect(req.body.redir || '/home'); 
      //next(); 
     } else { 
      console.log('not authenticated'); 
      res.render('logins/new.jade', {title: 'Login Failed', redir:''}) 
     } 
    }); 
}); 

no tengo mucho más que hacer en mi solicitud, sin embargo, ya que es todavía muy joven. Sé que no estoy destruyendo la sesión en ninguna parte; Lo comprobé.

Hice algunas pruebas más, y parece que esto es solo un problema cuando trato de usar la variable local en una página. Por ejemplo, aquí está mi punto de vista home.jade

 
div(data-role="page") 
    div(data-role="header") 
     a(href='/logout', data-icon='delete', data-ajax="false") Log out 
     h1= title 
     a(href='/account', data-icon='info', data-ajax="false") Account 

     != partial('user', user) 


    each jtl in job_task_lists 
     div(id=jtl.name, class = 'draggable_item', style='border:2px solid black;') 
      #{jtl.name} - #{jtl.description} 
     a(data-icon='plus') 


    div(data-role="footer") 
     h3 footer 

script(src="/javascripts/home.js") 

Si comento hacia fuera el usuario parcial, que hace que, de lo contrario me sale este tema Converting circular structure to JSON.

ACTUALIZACIÓN Así que después de conectar el eclipse y el depurador v8, he estado recorrer el código y sé donde está ocurriendo el mashup de sesión y objetos de usuario,

en node_modules/connect/lib/middleware/session/session.js

utils .union termina machacando los miembros del objeto de usuario en la sesión, causando la referencia circular. No estoy seguro de por qué (es probable que sea mi código)

+0

Ya asignados a req.session.user "u" en que la devolución de llamada. ¿Simplemente pasa el usuario: u trabaja para la llamada de renderizado, evitando esa referencia adicional? –

+0

No, eso también conduce al problema de referencia circular. Estoy asumiendo que esto es todo porque no estoy comprendiendo un cierre en particular ... Indagué en la implementación de la sesión dentro de connect - y console.log (sess) donde hace el stringify - y lo que obtengo se ve como un mashup de las variables de sesión (añadiré a la pregunta la estructura que obtengo) – dwerner

+0

Se está agregando a la sesión, con una referencia a sí mismo ya en sesión ... – dwerner

Respuesta

3

Esto fue un problema con los datos de la sesión que se están modificando en una vista.

Después de excavar mucho, descubrí que era un error en la forma en que se manejan los parciales en 2.5.8. Presenté un issue, y posteriormente un patch.(en caso de que alguien necesite esta información en una fecha futura) ya que npm todavía está publicando Express 2.5.8 AFAIK.

Gracias por su ayuda y @freakish @Ryan

+1

Buen trabajo. No sé por qué no pude reproducir el error. Me alegro de que logró arreglar esto! – freakish

Cuestiones relacionadas