【问题标题】:NodeJS HTTP - listen on other port than 80NodeJS HTTP - 侦听 80 以外的其他端口
【发布时间】:2023-04-11 06:44:04
【问题描述】:

我在 Windows 上运行 XAMPP 以在端口 80 上托管 Apache 服务器。现在我试图让 NodeJS 脚本在后台运行,但问题是它只能在端口 80 上侦听。如果是这样,一切可以正常工作,但我不能同时运行 Apache,因为 Apache 具有优先权,只为我的网站提供服务。 NodeJS 脚本甚至不听。

我的问题是:如何切换 NodeJS 脚本的监听端口(具体端口真的不重要),以便 Apache 仍然可以在端口 80 上运行,并且我可以从世界各地访问 NodeJS 脚本。

部分NodeJS代码:

const http = require('http');

const port = 8080;
const host = '0.0.0.0';




server = http.createServer( function(req, res) {
    if (req.method == 'POST') {
        var body = '';
        req.on('data', function (data) {
            body += data;
            doStuff(body);
        });
        res.writeHead(200, {'Content-Type': 'text'});
        res.end('received request successfully');
    }
    else {
        res.writeHead(405, {'Content-Type': 'text'});
        res.end('not allowed method ' + req.method + ', try again with GET or POST');
    }

})

server.listen(port, null, function(error){
  if(!!error){
    console.log("\x1b[41m%s\x1b[0m", "error while initializing listener on port " + port + ": " + error);
   }
   else{
    console.log("\x1b[32m%s\x1b[0m", "started listener at 'http://" + host + ':' + port + "'");}
 });

Additional information is in my other question which got flagged as duplicate.

【问题讨论】:

  • 您需要为此设置反向代理。谷歌一下
  • @AnkitAgarwal 谢谢,我会查一下
  • 更改端口时遇到什么错误?
  • @willascend 抱歉回复晚了。我没有错误。它正常启动。它只是无法获取任何数据。
  • 知道了。这表明服务器可能在指定的端口上运行。听起来问题是在不使用 url 中的端口的情况下访问节点服务器。请尝试反向代理以使其正常工作。它还可能有助于提供有关您如何设置 apache 服务器以及您希望如何从外部访问节点服务器的其他信息。

标签: node.js apache http xampp


【解决方案1】:

只需更改您的 node.js 服务器端口,例如:

var server = app.listen(8080, function() {
    console.log('Ready on port %d', server.address().port);
});

其中 8080 是 node.js 服务器的新端口。

【讨论】:

  • 这不起作用,即使我在路由器上打开了那个端口
  • 你能告诉我你是如何设置你的 node.js 服务器的吗?将您的代码嵌入到您的问题中
  • 我添加了sn-p。我不能发布所有内容,因为它用于我的工作。
  • 更改端口为 8000
【解决方案2】:

查看您的other question,它被标记为与此重复,您在那里获得了一些额外的信息,这些信息可能有助于阐明您的需求。具体来说,您提到以下内容:

我想用 NodeJS 托管多个 http 服务器,它们都可以获取和发送 http 请求。同时我想让Apache运行,占用80端口。如果我禁用Apache,让NodeJS在80端口运行,它会工作,但我不能让它们同时运行。

此脚本将在端口 8081 本地运行并接收请求,但我似乎无法通过 Internet 向它发送 AJAX 请求,即使在使用我的路由器转发端口后:

我认为@ankit-agarwal 可能是正确的,因为您需要一个反向代理设置来将流量转发到您的不同后端。假设您有一个面向外部的 IP 地址,您应该能够使用它们正在侦听的端口访问每个后端。例如,如果你的机器暴露的公网IP地址是100.120.110.43:

+---------+------+-------------------------------------+
| Backend | Port |             Web Address             |
+=========+======+=====================================+
| Apache  |   80 | 100.120.110.43 or 100.120.110.43:80 |
| Node1   | 8080 | 100.120.110.43:8080                 |
| Node2   | 8081 | 100.120.110.43:8081                 |
+---------+------+-------------------------------------+

如果您想在不指定端口的情况下访问每个后端,则必须有一些方法来告诉您的内部网络根据请求为哪个后端提供服务。一种方法是使用基于路径的路由,您可以在其中设置反向代理以根据 url 中的路径将流量路由到不同的后端。您没有发布您的 Apache 配置,但您可以使用当前的 Apache 服务器来处理此问题,使用类似于以下的 ProxyPassProxyPassReverse 指令:

ProxyPass "/node1"  "http://100.120.110.43:8080/"
ProxyPassReverse "/node1"  "http://100.120.110.43:8080/"

ProxyPass "/node2"  "http://100.120.110.43:8081/"
ProxyPassReverse "/node2"  "http://100.120.110.43:8081/"

使用反向代理很酷的一点是,您不必向公众公开您的节点后端。假设您没有,它们只能从 0.0.0.0:port 的内部网络访问。

Listen 80
<VirtualHost *:80>
    DocumentRoot /www/apache
    ServerName www.apachefrontend.com
    ProxyRequests off
    ProxyPass /node1  http://0.0.0.0:8080/
    ProxyPassReverse /node1  http://0.0.0.0:8080/
    ProxyPass /node2  http://0.0.0.0:8081/
    ProxyPassReverse /node2  http://0.0.0.0:8081/
</VirtualHost>

您还可以指向只有您有权访问的不同主机/IP。

最后,如果您有不同的 DNS 记录指向不同的后端,您也可以使用 VirtualHost 和 ServerName。

Listen 80
<VirtualHost *:80>
    DocumentRoot /www/apache
    ServerName www.apachefrontend.com
</VirtualHost>
<VirtualHost *:80>
    ServerName www.nodebackend1.com
    ProxyRequests off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    <Location />
        ProxyPass /  http://0.0.0.0:8080/
        ProxyPassReverse /  http://0.0.0.0:8080/
    </Location>
</VirtualHost>
<VirtualHost *:80>
    ServerName www.nodebackend2.com
    ProxyRequests off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    <Location />
        ProxyPass /  http://0.0.0.0:8081/
        ProxyPassReverse /  http://0.0.0.0:8081/
    </Location>
</VirtualHost>

要使上述任何一项工作,您需要在 apache 中启用 mod_proxymod_proxy_http

这些可能不是最可靠的示例,我还没有测试过它们,但它们应该能证明这个想法。你可以了解更多here

【讨论】:

  • 感谢您的回答!我目前正在工作,无法测试,但我会确保在今天晚些时候尝试一下。
  • 我试着完全按照你说的做,并将第一段代码复制到 httpd.conf(我删除了 Listen 80,因为我已经有了它)。我还取消了 mod_proxy 和 mod_proxy_http 的注释。但是重新启动服务器导致 Apache 不想启动。这是我的 httpd.conf:pastebin.com/NHDzsLeV
  • 它没有启动,因为我没有将 DocumentRoot 放在引号中。现在它在 POST 请求上给了我一个 404 错误,这不是一个大问题,但现在 Apache 仍然接受请求并且不会将其重定向到 0.0.0.0:8081
  • 经过一些实验,我终于让它与您提供的第一个代码 sn-p 一起工作。问题是我错误地配置了我的请求,并且我的 httpd.conf 中有第二个 ServerName 杂散。非常感谢!
【解决方案3】:

我还没有真正理解你没有得到任何响应的意思,因为我运行了相同的代码并且它对我来说很好。

我在这里只注意到了一些东西(我在评论中为你保留了一个注释)

server = http.createServer( function(req, res) {
    if (req.method == 'POST') {
        var body = '';
        req.on('data', function (data) {
            body += data;
            doStuff(body); //you haven't defined doStuff so you will end up with a error message on this line, but you sever will still run fine
        });
        res.writeHead(200, {'Content-Type': 'text'});
        res.end('received request successfully'); 
    }
    else {
        res.writeHead(405, {'Content-Type': 'text'});
        res.end('not allowed method ' + req.method + ', try again with GET or POST');
    }

})

运行你的post请求时,不要忘记在你的body区域添加"",选择raw然后选择JSON(application/json) 。这对你来说应该没问题,除了你可能会得到一个reference error,如下所示,但你仍然应该得到received request successfully的回复。

错误

            doStuff(body);
            ^

ReferenceError: doStuff is not defined

确保您正在做同样的事情,如果您的问题得到解决,请告诉我们。

【讨论】:

  • doStuff(body); 只是一个占位符。实际上,我还有另一个功能。我从来没有在服务器上收到任何请求,它没有显示任何类型的活动。
  • 另外,作为迟到一年的后续行动:本地主机从来都不是问题。我希望它可以通过互联网访问
  • 哦,太好了!所以我假设你当时一切都很好。
  • 在出现问题时运行不正常,但我可以使用反向代理修复它
  • 好的,那么这是否意味着您到现在仍然有同样的问题?
【解决方案4】:

您的8080 端口上似乎已经运行了一些东西。只需更改到另一个端口。例如7000 并确保您调用 nodejs 应用程序的所有请求都像这样

localhost:7000 // Normal we run at port 80 url simply localhost without port

【讨论】:

  • 该端口上没有运行任何东西。我已经检查过netstat。我也试过8081。
【解决方案5】:

这与在共享主机中使用 NodeJ 的情况相同。我已经写了一篇关于它的博文here

让我摘录。

  1. 只需在 8080 端口运行 NodeJS 服务器即可。

  2. 现在,假设您的 Apache 服务于 http://example.com,在您的 public_htmlwww 中创建一个文件夹。假设名称是server。所以,你的新文件夹路径是http://example.com/server

  3. 在服务器文件夹中创建一个.htaccess 文件
  4. 添加以下行,

    RewriteEngine On
    RewriteRule ^$ http://127.0.0.1:8080/ [P,L] #which is your node server ip:port
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ http://127.0.0.1:8080/$1 [P,L] #same ip:port
    

这会将来自http://example.com/server 的所有请求重定向到您的节点服务器。

【讨论】:

  • 这给了我一个 500 内部服务器错误。
  • 你能检查一下请求是否真的到达了nodejs服务器吗?因为我有相同的设置为我工作就好了。
  • 不,不是。我只是收到 500 错误。
  • 您是否也添加了 cmets?像 #which is..#same ip 。请删除它并尝试。刚刚在我的本地设置中测试过
  • 这并没有改变任何事情。
【解决方案6】:

如果我想在同一个端口使用 Apache 和 Nodejs: npm http-proxy-middleware

1.设置 Apache 端口 = 81

[apache 目录]/conf/httpd.conf

~59:听 81

2。设置nodejs APP端口=3050

server.listen(3050); // 在 linux 端口

3。使用第三个代理APP(http-proxy-middleware)

  // https://www.npmjs.com/package/http-proxy-middleware
  var express = require('express');
  var proxy = require('http-proxy-middleware');

  // proxy middleware options
  var options = {
      target: 'http://localhost:81', // target host ROOT
      changeOrigin: true, // needed for virtual hosted sites
      ws: true, // proxy websockets
      pathRewrite: {
          // '^/api/old-path' : '/api/new-path',     // rewrite path
          // '^/api/remove/path' : '/path'           // remove base path        
      },
      router: {
          // Examples:
          // when request.headers.host == 'dev.localhost:3000',
          // override target 'http://www.example.org' to 'http://localhost:8000'
          // 'dev.localhost:3000' : 'http://localhost:8000',
          // 'localhost:9000': 'localhost:9002/sub',                 
          // '/sub': 'http://localhost:9002',

          'localhost': 'http://localhost:81',         //Root to Apache
          'sub.localhost': 'http://localhost:3050',  // internal
          'sub.mydomain.com': 'http://localhost:3050', //external
      },
  };

  // create the proxy (without context)
  // var proxy_wp = proxy(options_wp);
  var proxy_node = proxy(options);

  // mount `exampleProxy` in web server
  var app = express();
  app.use(proxy_node);
  app.listen(80);

然后:

  1. localhost:80 - 是 apache 站点
  2. sub.localhost:80 - 节点
  3. localhost:80/sub - 节点,如果你设置了

对于任务运行器,我使用 npm PM2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-25
    • 2019-08-21
    • 2019-05-05
    • 2019-11-08
    • 1970-01-01
    • 2019-09-15
    • 2016-03-28
    相关资源
    最近更新 更多