2014-06-29 80 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

相關問題