【问题标题】:How to make a HTTP request using Node.js upon user input?如何根据用户输入使用 Node.js 发出 HTTP 请求?
【发布时间】:2019-03-18 01:44:17
【问题描述】:

所以我在 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

目前,我认为这是因为 requestCommand 函数在错误处理之前结束(在发出 error 事件并调用返回错误的回调函数之前),因为 http.request 的回调函数显然是异步,在服务器响应或发出错误之前,函数结束,因此不返回任何内容 (undefined)

所以我的问题是:我可以在异步命令完成之前保持该函数运行吗?

或者如果这是不可能的,是否有不同的方法来解决这个问题?当用户触发某个事件(例如数据输入)时,您将如何向该服务器发送请求?

编辑:我真的对使用 3rd 方模块不感兴趣,因为我已经可以了。这个项目真的没有意义,只供我学习,所以我只使用核心模块。更具体地说,我只使用 HTTP 来发出请求(不是同步请求等)

【问题讨论】:

  • 我是新人,所以如果我没有任何意义,请要求澄清或指出我应该改进我的问题的哪一部分。

标签: javascript node.js asynchronous synchronization


【解决方案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();
}
});

【讨论】:

  • 我能否澄清一下,该函数返回一个承诺,然后您可以在异步函数中等待,直到它解决或拒绝。对吗?
  • @dennis 完全正确
猜你喜欢
  • 1970-01-01
  • 2011-06-04
  • 2011-12-19
  • 2020-01-29
  • 1970-01-01
  • 2017-05-21
  • 2019-10-20
  • 1970-01-01
  • 2020-09-02
相关资源
最近更新 更多