¿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 JSONerrores, (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)
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? –
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
Se está agregando a la sesión, con una referencia a sí mismo ya en sesión ... – dwerner