2017-04-18 3 views
0

하나의 이상한 문제가 있습니다. 양식을 제출하면 양식 URL로 리디렉션되어 빈 페이지가 표시됩니다. 다시로드하면 데이터가 표시됩니다.노드 js 게시물 요청은 두 번째로만 작동합니다.

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

레이아웃

,617 확장 - 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') 

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가 app.js

block content 
    h1= "Result" 
    pre= data 

나는 그것이 http://172.18.0.60:3000/runcommand 만 표시 (H1)로 리디렉션됩니다 형성 제출, 나는 다시 다시로드 할 때 그것은 데이터를 표시합니다.

왜 이런 식으로 행동합니까?

답변

4

exec()은 비동기이므로 res.render()으로 전화를 한 후에 작업이 완료됩니다. 따라서 exec() 호출이 완료된 후에 만 ​​렌더링해야합니다. 약속과 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}); 
       } 
      }); 
     }); 
    } 
}); 

추신 :

는 다음 카운터를 사용하여 계획입니다 이 코드는 모든 클라이언트가 임의의 arbitray 프로그램을 서버에서 실행할 수있는 것처럼 보입니다 (경로에 있거나 전체 경로를 구성 할 수있는 경우). 그것은 매우 위험한 것처럼 보입니다.

P.P.S. tmp에있는 다른 요청에 대해 여러 요청을 처리 할 수 ​​있으므로 서버를 사용하는 여러 사용자가 원래 코드에서 수행 한 것처럼 처리기 외부에 tmp이 누적되면 재앙입니다. 이와 같이 누적 된 데이터는 요청 처리기 내부의 로컬 변수 또는 요청 객체의 등록 정보에 있어야 프로세스의 다른 요청과 충돌 할 수 없습니다.

+0

대단원! 설명. –