2017-04-18 17 views
0

我有一個奇怪的問題,當我提交表單時,它重定向到表單動作URL,然後顯示空白頁面。當我重新加載它時,它將顯示數據。node js post request只能第二次使用

index.jade - http://172.18.0.60:3000/

form#command(action='runcommand', method='post') 
    input#cmdls(type='checkbox', name='cmdls', value='ls -la') 
    label(for='cmdls') List Files 
    br 
    input#cmdpwd(type='checkbox', name='cmdpwd', value='pwd') 
    label(for='cmdpwd') Print Working Directory 
    br 
    input#cmddate(type='checkbox', name='cmddate', value='date') 
    label(for='cmddate') Date 
    br 
    input.button(type='submit', value='Run') 

app.js

var tmp=""; 
app.post('/runcommand',function(req,res){ 

    for (var key in req.body) { 

      console.log(key); 
      function puts(error, stdout, stderr) { sys.puts(stdout) } 
      exec(req.body[key], function(error, stdout, stderr) { 
       if (!error) { 
        tmp+=stdout;      
       } else { 
       tmp+=stderr; 
       } 
      }); 

    } 

    res.render("result",{ data: tmp }); 

}); 

result.jade - http://172.18.0.60:3000/runcommand

延伸佈局

block content 
    h1= "Result" 
    pre= data 

當我提交的形式,它會重定向到http://172.18.0.60:3000/runcommand只顯示H1,當我再次重新加載它,它顯示數據

它爲什麼表現如此呢?

回答

4

exec()是異步的,因此它會在您撥打res.render()後完成。所以,只有在所有exec()調用都完成後,您才需要渲染。如果您使用promises和Promise.all()來跟蹤所有exec()調用完成的情況,那麼這可能會更容易編碼,但您也可以使用計數器來了解最後一次調用的完成時間。

下面是一個使用計數器的方案:

app.post('/runcommand', function(req, res) { 

    let keys = Object.keys(req.body); 
    let cnt = 0; 
    let tmp = ''; 
    if (!keys.length) { 
     // render something when there were no keys 
     res.render(...) 
    } else { 
     keys.forEach(function(key) { 
      console.log(key); 

      exec(req.body[key], function(error, stdout, stderr) { 
       if (!error) { 
        tmp += stdout; 
       } else { 
        tmp += stderr; 
       } 
       ++cnt; 
       // if all exec calls have finished, the render 
       if (cnt === keys.length) { 
        res.render("result", {data:tmp}); 
       } 
      }); 
     }); 
    } 
}); 

附:這段代碼看起來像它允許任何客戶端在服務器上運行任何仲裁程序(如果它在路徑中或者它們可以構造完整路徑)。這似乎很危險。

P.P.S.在處理器之外積累tmp就像您在原始代碼中執行的操作一樣,對於使用您的服務器的多個用戶來說是一場災難,因爲多個請求可能會對tmp中的其他值產生影響。像這樣的累計數據需要位於請求處理程序中的局部變量中或請求對象中的屬性中,以便它永遠不會與正在處理的其他請求衝突。

+0

太棒了!說明。 –

相關問題