2013-04-26 47 views
0

訪問POST數據和設置cookie的我正在寫一個應用程序,需要在POST請求,並設置一個cookie從POST信息拉昇。我被卡在一個catch 22.在第一個代碼示例中,我可以設置cookie但不能訪問數據,在第二次我可以訪問數據但不能設置cookie。我確信我錯過了中間件工作原理的一些基本概念,但我無法爲我的生活找到所需的信息。快遞:無法在同一時間

下面的代碼創建如預期的Cookie,但我的變量後變得不確定

var express = require('express') 
    , routes = require('./routes') 
    , user = require('./routes/user') 
    , handshake = require('./routes/handshake') 
    , http = require('http') 
    , path = require('path'); 

var app = express(); 
app.set('port', process.env.PORT || 3000); 
app.set('views', __dirname + '/views'); 
app.use(express.cookieParser()); 
app.use(express.bodyParser()); 
app.use(express.methodOverride()); 
app.use(function (req, res, next) { 
    var cookie = req.cookies.cokkieName; 
    console.log("cookie_name" , cookie); 
    if (cookie === undefined) 
    { 
      //cookie is set but I can't use req.post.xxxx. It"s always undefined 
     res.cookie("price", 111, { maxAge: 10000 }); 
     console.log('cookie has been created successfully'); 
    } 
    else 
    { 
     console.log('cookie exists', cookie); 
    } 
    next(); 
}); 

app.use(app.router); 
app.use(require('stylus').middleware(__dirname + '/public')); 
app.use(express.static(path.join(__dirname, 'public'))); 
app.post('/handshake', handshake.token); 

http.createServer(app).listen(app.get('port'), function(){ 
    console.log('Express server listening on port ' + app.get('port')); 
}); 

下面的代碼執行setCookie方法回調(因爲控制檯輸出顯示出來),並在控制檯上的正確定義變量,但該cookie未設置。

var express = require('express') 
    , routes = require('./routes') 
    , user = require('./routes/user') 
    , handshake = require('./routes/handshake') 
    , http = require('http') 
    , path = require('path'); 

var app = express(); 

app.set('port', process.env.PORT || 3000); 
app.set('views', __dirname + '/views'); 
app.use(express.cookieParser()); 
app.use(express.bodyParser()); 
app.use(express.methodOverride()); 


var setCookie = function (req, res, next) { 
    var cookie = req.cookies.cokkieName; 
    console.log("cookie_name" , cookie); 
    if (cookie === undefined) 
    { 

     res.cookie("price", 111, { maxAge: 10000 }); 
      //in the console the post.body.xxxx data appears correctly but no cookie!!! 
     console.log('cookie has been created successfully',post.body.xxx); 
    } 
    else 
    { 
     console.log('cookie exists', cookie); 
    } 
    next(); 
}; 
app.use(app.router); 
app.use(require('stylus').middleware(__dirname + '/public')); 
app.use(express.static(path.join(__dirname, 'public'))); 
app.post('/handshake', setCookie ,handshake.token); 
http.createServer(app).listen(app.get('port'), function(){ 
    console.log('Express server listening on port ' + app.get('port')); 
}); 

試圖讓代碼更具可讀性引入了太多與我的代碼無關的拼寫錯誤。我採取了這樣的建議,並以下面的方式改變了代碼,但它仍然沒有向客戶端寫入cookie。

var express = require('express') 
    , routes = require('./routes') 
    , user = require('./routes/user') 
    , handshake = require('./routes/handshake') 
    , http = require('http') 
    , crypt = require('crypto') 
    , io = require('socket.io') 
    , db = require('levelup')('./mydb') 
    , path = require('path'); 

var app = express(); 
app.use(express.cookieParser()); 
app.use(express.bodyParser()); 

var cookieMiddleware = function (req, res, next) { 
    var cookie = req.cookies.user; 
    console.log("cookie_name" , cookie); 
    if (cookie === undefined) 
    { 
     // no: set a new cookie 
     var random = Math.random().toString(); 
     random=random.substring(2,random.length);  
     sessionToken = Date.now() + random; 
     salt = sessionToken + req.body.address; 
     sha2 = crypt.createHash('sha256'); 
     sha2.update(sessionToken); 
     var price = req.body.price; 
     var encryptedSession = sha2.digest('hex'); 

    console.log('post body',price); 
     res.cookie('user','price' , { maxAge: 100000 }); 
     console.log('existing cookies', req.cookies); 
    } 
    else 
    { 
     console.log('cookie exists', req.cookies); 
    } 
    next(); 
}; 
//development only 
if ('development' == app.get('env')) { 
app.use(express.errorHandler()); 
} 

app.set('port', process.env.PORT || 3000); 
app.set('views', __dirname + '/views'); 
app.set('view engine', 'jade'); 
app.use(express.logger('dev')); 
app.use(express.session({secret: "TheSuperSecretStringForHashing"})); 
app.use(express.methodOverride()); 
app.use(app.router); 
//app.use(express.favicon()); 
app.use(require('stylus').middleware(__dirname + '/public')); 
app.use(express.static(path.join(__dirname, 'public'))); 
app.post('/handshake', cookieMiddleware , handshake.token); 
app.get('/', routes.index); 
app.get('/users', user.list); 


var server = http.createServer(app).listen(app.get('port'), function(){ 
    console.log('Express server listening on port ' + app.get('port')); 
}); 

io = io.listen(server); 

io.sockets.on('connection', function (socket) { 
     socket.emit('news', { hello: 'world' }); 
     socket.on('my other event', function (data) { 
     console.log(data); 
     }); 
    }); 

的handshake.js處理器

exports.token = function(req, res){ 
    req.body.title = 'Payment Portal'; 
    res.render('payment_init', req.body); 
}; 
+0

我只掃描代碼簡單,但由於使用的是全球中間件的cookie會不會是另一請求後請求之前設置呢?例如,一個favicon請求也會被全局中間件處理,除非您在cookie中間件之前終止該請求。這就是爲什麼你應該把你的靜態中間件放在最頂層的原因(你沒有這麼做)。因此,對於靜態文件,您的Cookie中間件也在運行。如果你想只在「/握手」路線,你可以做app.post(「/ handskake」,cookieMiddleware,handskake.token)運行的cookie中間件。 – Pickels 2013-04-26 16:10:50

+0

嗨@皮克爾感謝您的迴應。我在理解你的幾點觀點時遇到了一些麻煩。 「...一個favicon請求也會被全局中間件處理,除非您在cookie中間件之前終止該請求」。實際上,我在Cookie之前確實擁有全球圖標(我將其刪除以使代碼更具可讀性),但我不清楚「結束請求」的含義。此外,「對於靜態文件,您的Cookie中間件也在運行。」我不清楚爲什麼這是不好的。如果它使用靜態文件運行,那麼應該設置cookie。這不是我想要發生的事嗎?提前致謝。 – Boso 2013-04-26 22:59:33

+0

別的東西,我注意到的是,你使用req.post.xxx應該req.body.xxx。 '結束那個請求'我的意思是說,如果中間件做的是事情,而下面的中間件不需要處理任何事情,它會結束請求,而不是接下來的調用。因此,如果靜態中間件發現您的url與磁盤上的文件相匹配,它將提供該文件,而不是接下來的調用。這樣您就不會運行與提供靜態文件無關的額外中間件。 – Pickels 2013-04-26 23:46:36

回答

0

您正在檢查名爲cokkieName餅乾,但你設置cookie的名稱爲price

嘗試改變這一到:

var cookie = req.cookies.price; 

cookie現在應該包含您的cookie的值。

+0

是的,這是一個錯字,但它仍不能解釋爲什麼我無法訪問發佈數據。我很確定Pickles對我的問題的迴應解釋了發生了什麼,但我仍然在閱讀文檔,試圖完全理解他的答案。 – Boso 2013-04-26 23:03:01