我正在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.
答案 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服务器通过ProxyPass和ProxyPassReverse指令来处理此配置,如下所示:
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_proxy
和mod_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');
}
})
在运行发布请求时,请不要忘记在您的正文区域添加""
,选择 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
让我摘录
只需在
8080
端口运行NodeJS服务器。现在,假设您的Apache服务在http://example.com,在
public_html
或www
中创建一个文件夹。假设名称为server
。因此,您的新文件夹路径为http://example.com/server- 在服务器文件夹中创建一个
.htaccess
文件添加以下行,
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
重定向到您的节点服务器。
答案 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);
然后:
对于任务运行程序,我使用 npm PM2