因此,我在node.js中启动了这个简单的项目,客户端在其中发送了一个POST请求,该请求的主体中包含Windows CMD命令。
服务器接收到POST请求,提取CMD命令,然后在运行该命令后,以该命令的输出作为响应。
当我发出一个请求时,此方法很好用,但是随后我设置了一个系统,反复询问用户该命令,然后以输入的命令作为正文发送POST请求。
这是客户端代码:(不包含服务器端,因为它无关紧要)
var http = require("http");
var readline = require("readline");
var rl = readline.createInterface(process.stdin, process.stdout);
var options = {
hostname: "localhost",
port: 3001,
path: "/",
method: "POST",
headers: {
"Content-Type": "text/plain", // all command must be string
"Content-Length": 0 // changes based on what the command is
}
};
function requestCommand(hostname, port, command) {
// Some of the options of the request need to be changed based on
// what the command is
options.hostname = hostname;
options.port = port;
options.headers["Content-Length"] = command.length;
var req = http.request(options, function(res) {
console.log(`Got response. Status code: ${res.statusCode}`);
var resData = "";
res.setEncoding("utf-8");
res.on("data", function(chunk){
resData += chunk
});
res.on("end", function(){
return resData;
})
})
req.on("error", function (e){
return "\n\n\n ---------------\nERROR OCCURED IN THE REQUEST.\nREQUEST NOT SENT\n--------------" + e.stack;
})
req.write(command);
req.end();
}
rl.setPrompt("What command would you like to request from the server?: ");
rl.prompt();
rl.on("line", function(data){
if (data === "exit") {
console.log("\n\n\Exiting appplication...\n\n");
process.exit();
} else {
console.log("processing..");
var out = requestCommand("localhost", 3001, data);
console.log(`\n\n${out}\n\n`);
rl.prompt();
}
});
如果我在不首先创建服务器的情况下运行它,则没有得到错误消息,而是得到undefined
。
当前,我认为这是因为requesthttp函数在处理错误之前结束(在发出error
事件之前,并且调用了返回错误的回调函数),因为http.request的回调函数显然是异步的,并且在服务器响应或发出错误之前,该函数结束并因此不返回任何内容(undefined
)
所以我的问题是:在异步命令完成之前,我可以一直运行该功能吗?
或者这是不可能的,是否有其他方法?在用户触发某些事件(例如数据输入)时,您将如何向该服务器发送请求?
编辑:我已经对使用第三方模块确实不感兴趣。这个项目真的没有意义,仅在这里供我学习,因此我仅使用核心模块。更具体地说,我仅使用HTTP发出请求(而不是同步请求,例如e.t.c。)
答案 0 :(得分:1)
requestCommand
必须返回一个用resData
解析并因错误而被拒绝的承诺:
function requestCommand(hostname, port, command) {
return new Promise((resolve, reject) => { // immeadiately return a Promise that can be resolved/rejected later
// Some of the options of the request need to be changed based on
// what the command is
options.hostname = hostname;
options.port = port;
options.headers["Content-Length"] = command.length;
var req = http.request(options, function(res) {
console.log(`Got response. Status code: ${res.statusCode}`);
var resData = "";
res.setEncoding("utf-8");
res.on("data", function(chunk){
resData += chunk
});
res.on("end", function(){
resolve(resData); // resolve, return won't work here
});
});
req.on("error", function (e){
reject(e); // reject here, don't handle it
});
req.write(command);
req.end();
});
}
这样,您可以简单地使请求处理程序async
,然后使await
成为函数调用:
rl.on("line", async function(data){ // make the function async so that we can work with promises more easily
if (data === "exit") {
console.log("\n\n\Exiting appplication...\n\n");
process.exit();
} else {
console.log("processing..");
try {
var out = await requestCommand("localhost", 3001, data); // "await" lets async code look like sync code, but it is still async
console.log(`\n\n${out}\n\n`);
} catch(e) { // the reject() call will end up here
console.log("invalid command " + e.stack); // handle here
}
rl.prompt();
}
});