NodeJS HTTP-在80以外的其他端口上侦听

时间:2018-10-22 09:20:55

标签: node.js apache http xampp

我正在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.

6 个答案:

答案 0 :(得分:4)

查看您的other question,它被标记为与此副本的副本,您那里还有一些其他信息,这些信息可能有助于阐明您的需求。具体来说,您提到以下内容:

  

我想用NodeJS托管多个http服务器,这些服务器都获取和发送http请求。同时,我想运行占用端口80的Apache。如果我禁用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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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

我只在这里注意到了一些东西(我在评论中为您留了一个字条)

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');
    }

})

Postman image

在运行发布请求时,请不要忘记在您的正文区域添加"",选择 raw ,然后选择 JSON(应用程序/ json)。这对您来说应该不错,除了您可能会得到一个reference error,如下所示,但是您仍然应该得到received request successfully的答复。

错误

            doStuff(body);
            ^

ReferenceError: doStuff is not defined

确保您正在做相同的事情,并让我们知道您的问题是否已解决。

答案 3 :(得分:0)

似乎您的8080端口上已在运行某些内容。只需更改为另一个端口即可。例如7000 并确保所有这样要求您调用nodejs应用的请求

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

答案 4 :(得分:0)

这与在共享主机中使用NodeJ的情况相同。我为此写了一篇博文here

让我摘录

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

  2.   
  3. 现在,假设您的Apache服务在http://example.com,在public_htmlwww中创建一个文件夹。假设名称为server。因此,您的新文件夹路径为http://example.com/server

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

    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
    
  8.   

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

答案 5 :(得分:0)

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

1。设置Apache端口= 81

[apache dir] /conf/httpd.conf

  

〜59:听81

2。设置nodejs APP端口= 3050

  

server.listen(3050);   //在linux端口上<1000需要root特权

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