无法从 localhost 以外的任何地方向 Node.js HTTP Web 服务器发送 POST 请求

Unable to send POST request to Node.js HTTP Webserver from anything other than localhost

我目前正在尝试将 text/data 从客户端浏览器发送到 Node.js 网络服务器,但是每当我使用本地主机以外的任何东西时,我都会收到“POST ERR_CONNECTION_TIMED_OUT" 错误。

这是客户端 (html) 的代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Client</title>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <textarea id="stream" rows="8" cols="80" oninput="update(this.value)"></textarea>
    <script>

      function update(v) {
        let data = {
          text: v
        };
        send(data);
      }

      function send(d) {
        axios.post(
          "http://<the server IP>:34567",
          JSON.stringify(d)
        ).then(res => {
          // do nothing
        }).catch(error => {
          console.error(error);
        });
      }
    </script>
  </body>
</html>

和服务器代码(node.js;http作为节点模块安装):

const http = require("http");

const port = 34567;

http.createServer(async (req, res) => {

  const headers = {
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "OPTIONS, POST, GET",
    "Access-Control-Max-Age": 2592000,
    "Access-Control-Allow-Headers": "*"
  };

  switch (req.method) {
    case "GET":
      // Write success header:
      res.writeHead(200, headers);

      // Respond:
      res.write("not yet implemented");
      // Close:
      res.end();
      return;
    break;
    case "POST":

      const buffers = [];

      for await (const chunk of req) {
        buffers.push(chunk);
      }

      const data = Buffer.concat(buffers).toString();

      console.log(JSON.parse(data).text); // Should print the text from the textarea

      res.writeHead(200, headers);
      res.end();
      return;
    break;
    case "OPTIONS":
      res.writeHead(204, headers);
      res.end();
      return;
    break;
  }

  res.writeHead(405, headers);
  res.end(`${req.method} is not allowed for the request.`);

}).listen(port, () => {
  console.log(`[INFO] Server is active on port ${port}.`)
});

我已经转发了 34567 端口 (TCP)。

每当我在主机上时,我使用“localhost”作为服务器 IP,一切正常。客户端文本区域中的文本会立即显示在服务器控制台中。但是,当我将其更改为我的实际 IP(看起来像 12.34.567.890)时,一切都停止了。我通常会得到我之前提到的“POST ERR_CONNECTION_TIMED_OUT”错误,但是过了一段时间,服务器会(有时,不总是)接收数据(我说的就像......几乎一分钟后,这没有意义)。

我做错了什么?

感谢任何帮助。谢谢

您似乎没有检查路由,您只是在检查 http 方法(post、get 等)

下面的例子做了一些事情..

  • 让你监听特定的路由
  • 让您可以监听那些特定路由上的特定 http 方法

假设您有一个包含两个文件的文件夹,server.jshome.html,如下所示。如果您 运行 node server.js 然后打开浏览器并转到 localhost:34567/home 并打开浏览器控制台。从那里开始打字。您应该会看到在客户端和服务器端记录的数据。

发生这种情况的原因是浏览器很奇怪。如果您不从服务器提供 html 文件,则您的浏览器具有阻止您与您的服务器(或任何服务器)对话的安全功能。基本上,当您尝试通过 XHR (axios/fetch/etc) 进行通信时,浏览器中的 url 不能以 file:// 开头。

server.js

const http = require("http");
const fs = require("fs");
const fspath = require("path");
const url = require("url");

const server = http.createServer(async (request, response) => {
  const path = url.parse(request.url).pathname;
  switch (path) {
    /**
     * @route '/home' description for route
     * @methods (GET)
     */
    case "/home": {
      switch (request.method) {
        case "GET":
        default: {
          try {
            const html = await fs.readFileSync(fspath.resolve("./home.html"));
            response.writeHead(200);
            response.write(html);
          } catch (e) {
            console.error(e);
            response.writeHead(500);
            response.write("unable to read home html : " + e);
          }
          response.end();
        }
      }
    }

    /**
     * @route '/update'
     * @methods (POST)
     */
    case "/update": {
      switch (request.method) {
        case "POST": {
          console.log("in /update POST");
          const buffers = [];
          for await (const chunk of request) {
            buffers.push(chunk);
          }
          const data = Buffer.concat(buffers).toString();
          console.log(JSON.parse(data));
          response.end();
        }
        default: {
          response.end();
        }
      }
    }
    default: {
      response.end();
    }
  }
});

server.listen(34567);

const serverAddress = server.address();
const serverIp = serverAddress.address === "::" ? "localhost" : serverAddress.address;

console.log(`Server listening at : ${serverIp}:${serverAddress.port} : go to http://localhost:34567/home`);

home.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Client</title>
    <!-- script src="https://unpkg.com/axios/dist/axios.min.js"></script -->
  </head>
  <body>
    <textarea id="stream" rows="8" cols="80" oninput="update(this.value)"></textarea>
    <script>
      async function update(v) {
        let data = {
          text: v,
        };
        await send(data);
      }

      async function send(d) {
        try {
          const res = await fetch("/update", {
            method: "POST",
            body: JSON.stringify(d),
          });
          console.log(res);
        } catch (e) {
          console.error(e);
        }
        // ~
        // REMOVED : sorry, fetch was just easier..
        // ~
        // axios.post(
        //   "http://<the server IP>:34567",
        //   JSON.stringify(d)
        // ).then(res => {
        //   // do nothing
        // }).catch(error => {
        //   console.error(error);
        // });
      }
    </script>
  </body>
</html>