2012-03-05 16 views
5

Cosa c'è che non va qui?Errore ExpressJS res.render() (JSON.stringify non può funzionare su riferimento circolare)

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

Si porta a

Converting circular structure to JSON
errori, (risultati in elemento sessione che contiene un riferimento utente circolare.)

 

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

 

ho aggiunto un log in 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); 
... 

Questo quello che mi aspetto che la sessione assomiglia, in termini di struttura:

 
{ 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 } } 

Ma ecco cosa ho trovato:

 
{ 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) 

vedere come l'oggetto utente è nidificato?

  • Si noti che questa volta non ha mandato i valori in modo esplicito con 'locali' ma è finito in uno (questo è l'origine del riferimento circolare.

Sembra che la sessione è . utilizzati per trasferire gli oggetti alla vista

Qui è la mia unica middleware (si legge solo dalla sessione):

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

e l'unica volta che modifico il req.session è in questo percorso:

 
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:''}) 
     } 
    }); 
}); 

Non ho molto altro succede nella mia domanda ancora, in quanto è ancora molto giovane. So che non sto distruggendo la sessione da nessuna parte; Ho controllato.

Ho fatto qualche altro test, e sembra che questo sia solo un problema quando cerco di usare la variabile locale su una pagina. Per esempio, ecco la mia 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") 

Se io commento l'utente parziale, rende, altrimenti ottengo questo problema Converting circular structure to JSON.

UPDATE Così, dopo agganciando eclisse e il debugger v8, ho passando attraverso il codice e so dove il mashup di sessione e utente oggetti si sta verificando,

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

utils .union finisce per schiacciare i membri dell'oggetto utente nella sessione, causando il riferimento circolare. Non so perché (probabilmente il mio codice)

+0

È già assegnati req.session.user a "u" in quel di callback. Fa semplicemente passare l'utente: si lavora per la chiamata di rendering, evitando quel riferimento extra? –

+0

No, questo porta anche al problema di riferimento circolare. Suppongo che tutto ciò sia dovuto al fatto che non sto comprendendo una particolare chiusura ... Ho scavato nell'implementazione della sessione all'interno di connect - e console.log (sess) dove esegue il stringify - e quello che ottengo assomiglia un mashup delle variabili di sessione (aggiungo alla domanda la struttura che ottengo) – dwerner

+0

Viene aggiunto alla sessione, con un riferimento a se stesso già in sessione ... – dwerner

risposta

3

Si è verificato un problema con i dati di sessione modificati in una vista.

Dopo aver scavato molto, ho scoperto che si trattava di un bug nel modo in cui i partial sono gestiti in 2.5.8. Ho inviato un issue e successivamente uno patch.(nel caso qualcuno abbia bisogno di queste informazioni in una data futura) poiché npm continua a servire Express 2.5.8 AFAIK.

Grazie per il vostro aiuto e @freakish @ Ryan

+1

Buon lavoro, non so perché non sono riuscito a riprodurre l'errore. riuscito a risolvere questo! – freakish

Problemi correlati