2014-06-29 73 views
2

所以,我一直在努力与这些几个小时了。当我使用AJAX将某些东西发布到服务器时,会话将不会被发送到服务器,但它没有AJAX就能正常工作,比如点击链接,注销等,这让我无法忍受拉我的头发。无论如何,这些都是我的代码:req.session undefined only with AJAX

var express = require('express'), // express 4 
mongoskin = require('mongoskin'), 
Busboy = require('busboy'), 
cookieParser = require('cookie-parser'), 
session = require('express-session'), 
mailer = require('nodemailer'), 
compress = require('compression'), 
morgan = require('morgan'), 
ect = require('ect'), 
suspend = require('suspend'), 
MongoStore = require('connect-mongo')(session); 

app.use(compress()); 
app.engine('.ect', renderer.render); 
app.set('env', 'development'); 
app.use(express.static(__dirname + '/public')); 
app.use(cookieParser()); 
app.use('/admin', session({ 
    secret : 'qlauwork secret yo', 
    name : 'qlauworks.sess', 
    proxy : true, 
    rolling : true, 
    cookie : { 
     maxAge : 1000 * 60 * 60 * 6 
    }, 
    store : new MongoStore({ 
     db : 'qlauworks', 
     auto_reconnect : true, 
     defaultExpirationTime : 1000 * 60 * 60 * 6 
    }), 
    unset : 'destroy' 
})); 

// ... etc etc 

app.post('/admin/login', function (req, res) { 
    var msg = {}; 
    var busboy = new Busboy({ headers : req.headers }); 
    busboy.on('field', function (fieldName, val) { 
     msg[fieldName] = val; 
    }); 
    busboy.on('finish', function() { 
     suspend.run(function *() { 
      msg.password = crypto.createHash('whirlpool').update(SALT).update(msg.password).digest('hex'); 
      var user = yield db.users.findOne({ username : msg.username, password : msg.password }, suspend.resume()); 
      if (!user) { 
       return res.json({ error : 'Wrong username or password' }); 
      } 
      // create session token 
      var token = yield crypto.randomBytes(32, suspend.resume()); 
      token = token.toString('hex'); 
      yield db.users.update({ username : msg.username }, { $set : { token : token } }, { upsert : true }, suspend.resume()); 
      req.session.token = token; 
      res.redirect('/admin/forms'); 
     }, function (err) { 
      if (err) { 
       console.log('login: ', err); 
       res.send('Server error'); 
      } 
     }); 
    }); 
    req.pipe(busboy); 
}); 

// this is the logout and forms, works just fine 
app.get('/admin/logout', auth, function (req, res) { 
    suspend.run(function *() { 
     var token = req.session.token; 
     yield db.users.update({ token : token }, { $unset : { token : true } }, suspend.resume()); 
     delete req.session.token; 
     req.session.destroy(function (err) { 
      if (!err) { 
       res.clearCookie('qlauworks.sess', { path : '/' }); 
       res.redirect('/admin'); 
      } 
     }); 
    }, function (err) { 
     if (err) { 
      console.log('logout: ', err); 
      res.json({ error : 'Server error' }); 
     } 
    }); 
}); 

app.get('/admin/forms', auth, function (req, res) { 
    res.send(formPage); 
}); 

// and this is the auth middleware, could logout and moving around the admin page 
// but req.session always undefined if comes from an AJAX request 
function auth (req, res, next) { 
    suspend.run(function *() { 
     console.log(req.session); 
     console.log('=====================================================') 
     if (!req.session.token) { 
      return res.json({ error : 'Invalid token' }); 
     } 
     var user = yield db.users.findOne({ token : req.session.token }, suspend.resume()); 
     if (!user.username) { 
      return res.json({ error : 'Invalid token' }); 
     } 
     next(); 
    }, function (err) { 
     if (err) { 
      console.log('auth: ', err); 
      res.json({ error : 'Server error' }); 
     } 
    }); 
} 

,这是客户端

$.post('/api/item/new', elem, function (rep) { 
    thisForm.find('input[type="submit"]').attr('disabled', false); 
    if (rep.error) { 
     $('#alert-multi').removeClass('success').addClass('alert').text(rep.error); 
    } else { 
     $('#alert-multi').removeClass('alert').addClass('success').text('Success'); 
     $('input[type="reset"]').click(); 
     for (var i = 0; i < len; i++) { 
      $('#preview-multi' + i).attr('src', ''); 
      $('#multi' + i).attr('data-image-src', ''); 
     } 
    } 
}); 

那么,我该如何解决这个问题?

+0

其中是你的服务器端代码中'/ api/item/view'的映射吗? – soulcheck

+0

@soulcheck就像这样'app.post('/ api/item /:whatdo',auth,function(req,res){' – user3102569

+0

请发布整个映射,因为这是有趣的部分 – soulcheck

回答

0

它看起来像是在/admin上挂载了会话中间件,但您正试图拨打/api/item/view

这不会因为使用express.use(path, middleware)将调用middleware只适合req.url包含path请求工作。

要么安装会话中间件上/(不使用path参数 - 简单express.use(middleware)会做),或者改变你的AJAX网址开头为/admin(你想要做的可能不是)。

+0

哎哟,我不能再多谢你了,你让我看起来像一个工具,现在感觉就像现在一样,我只是浪费了大约6个小时的时间来解决这个问题,谢谢你,非常善良的先生。 – user3102569

+0

Glad有时帮助别人看看代码有助于你花更多的时间看看它:)发生在我身上的很多次。 – soulcheck

+0

的确如此。现在我必须帮助某人偿还恩惠:) – user3102569

相关问题