req.session只有使用AJAX才能定义

所以,我现在一直在挣扎几个小时。 当我使用AJAX将某些东西发送到服务器时,会话将不会被发送到服务器,但是如果没有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', ''); } } }); 

那么,我该如何解决呢?

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

这不会像使用express.use(path, middleware)只会为req.url包含path请求调用middleware

将会话中间件挂载到/ (不使用path参数 – 简单express.use(middleware) ),或者将你的ajax url改为/admin (可能不是你想要的)。