Node.js/Express.js应用只能在3000端口运行

117

我在我的服务器上有一个运行在 Node.js/Express.js 上的应用程序,但只能在 3000 端口才能正常工作。我正在尝试找出原因,以下是我找到的情况:

  • 如果不指定端口号 (app.listen()),应用程序可以运行,但无法加载网页。
  • 如果使用 3001 端口 (app.listen(3001)) 或任何未被占用的端口,则应用程序可以运行,但无法加载网页。
  • 如果使用 2999 端口,则应用程序会抛出错误,因为该端口已被占用。
  • 仅当使用 3000 端口时,应用程序可以正常运行并且网页可以加载。

我知道 Express 应用程序默认使用 3000 端口。但奇怪的是,我的应用程序只有在明确指定它运行在 3000 端口 (app.listen(3000)) 时才能正常运行。

我在 /usr/bin/express 的第 220 行找到了这个信息:

app.set(\'port\', process.env.PORT || 3000);

如前所述:将端口设置为指定的值或者如果没有指定则设置为3000。

我该如何使我的应用在不同的端口(如8080或3001)上工作?

谢谢!

编辑:代码示例(非常简单的Node/Express应用程序)

var express = require("express");
var app = express();

app.get('/', function(req, res){
    res.send('hello world'); 
});

// Only works on 3000 regardless of what I set environment port to or how I set [value] in app.set('port', [value]).
app.listen(3000);

1
  1. .listen()需要一个“端口”,所以你不应该试图不使用它。
  2. 运行应用程序时是否出现任何错误?还是从浏览器中似乎无法访问?
  3. 你是在同一台机器上使用localhost:3000localhost:3001等方式访问网站吗?如果你正在使用两台机器,一台客户端和一台服务器,你需要在服务器上添加例外到防火墙,以允许Node接收来自客户端的请求。
- Jonathan Lonowski
你是如何启动应用程序的? - deitch
@Jonathan 很高兴了解到 .listen()。当我说“应用程序运行”时,这与您说“运行应用程序时没有错误”是相同的。当我说“网页无法加载”时,这与您说“从浏览器无法访问”是相同的。所有访问都来自同一台机器(我的服务器)。感谢您的反馈。 - Benjamin Martin
1
@deitch 当我想要设置环境端口变量时,我使用 $ supervisor app.js$ PORT=[PORT] node app.js。我会放上一个代码示例。 - Benjamin Martin
@BenjaminMartin 如果你遇到了其他程序正在使用该端口的错误,那么可能是因为你没有正确停止你的 node 实例。执行 ps -ax| grep node 命令,确保没有任何 node 进程已经绑定到你尝试使用的端口。 - EhevuTov
显示剩余4条评论
16个回答

137

如果你的app.js文件中有类似下面的内容,那么以下方法适用:

http.createServer(app).listen(app.get('port'),
  function(){
    console.log("Express server listening on port " + app.get('port'));
});

可以显式地将代码硬编码为使用您想要的端口,例如:

app.set('port', process.env.PORT || 3000);

这段代码的意思是将你的端口设置为环境变量 PORT,如果该变量未定义,则将其设置为字面值 3000

或者,可以使用你的环境来设置端口。通过环境设置端口有助于区分PRODUCTIONDEVELOPMENT,很多平台作为服务也会使用环境来根据规格设置端口,以及内部的Express配置。以下代码设置了一个环境键值对并启动你的应用程序。

$ PORT=8080 node app.js

关于您的代码示例,您想要类似这样的内容:

var express = require("express");
var app = express();

// sets port 8080 to default or unless otherwise specified in the environment
app.set('port', process.env.PORT || 8080);

app.get('/', function(req, res){
    res.send('hello world');
});

// Only works on 3000 regardless of what I set environment port to or how I set
// [value] in app.set('port', [value]).
// app.listen(3000);
app.listen(app.get('port'));

2
这真的很奇怪。我已经做了以下几步:1.将app.set()代码放入我的应用程序并将3000更改为8080。仍然只能在app.listen(3000)上运行。2.在运行节点应用程序时将环境端口变量更改为8080。仍然只能在app.listen(3000)上运行。3.转到/usr/bin/express(第220行)并将3000更改为8080。仍然只能在app.listen(3000)上运行。感谢您提供的信息。有什么需要重新启动的吗?据我所知,Express 无法重新启动,并且每次使用 node app.js 时都会重新启动 Node 应用程序。 - Benjamin Martin
@BenjaminMartin Express只是像其他模块一样的一个模块,所以只需简单的node app.js就可以启动它(我个人在开发和测试时使用nodemon)。你可能想到的是express命令行可执行文件,它是一个帮助进程,用于构建骨架文件结构。你能否发布你代码的gist? - EhevuTov
明白了。我通常只使用nodemonnohup一起来让我的应用程序无限期地运行。我没有使用express的CL可执行版本,因此每次重新启动我的node应用程序时它都必须重新启动。请参见我的原始帖子以获取附带代码的编辑。谢谢! - Benjamin Martin
这是另一种有用的更改端口的方法,但仍然只适用于端口为3000时。我开始怀疑我的服务器上是否有某些内容仅允许在特定端口上提供服务。虽然我不知道这个配置位于何处,但这可能是一个问题吗?FYI,我正在运行Ubuntu 10.04。 - Benjamin Martin
@BenjaminMartin 确保未设置 PORT=3000(或将其覆盖为 PORT=8080),确保没有其他正在使用该端口的 node 进程,并确保您没有明确指向那里。请确保直接复制我的代码并进行测试。如果这样做不起作用,那么可能出现了一些奇怪的问题(但不是非常奇怪,否则根本无法工作)。 - EhevuTov
显示剩余7条评论

37

bin/www 文件中,有一行代码:

var port = normalizePort(process.env.PORT || '3000');

尝试修改它。


1
我尝试在app.js中设置端口,但是这行代码被覆盖了。这是更改端口的正确位置。 - Neil

15

试试这个

$ PORT=8080 node app.js

1
谢谢你的回答 - 这只有在我在app.js中设置了app.listen(3000)时才有效。换句话说,像你所做的那样在运行应用程序时设置端口似乎无法覆盖app.listen()。 - Benjamin Martin
太好了。我在express中使用它:PORT=8000 npm start。所以你可以使用任何你想要的:D。 - Johan Hoeksma

14

请参考此链接。

尝试找到 bin>www 路径并尝试更改端口号...


12

修改Express框架上的监听端口的默认方法是修改bin文件夹中名为www的文件。

在那里,您会找到类似以下的一行

var port = normalizePort(process.env.PORT || '3000');

将数值3000更改为您希望的任何端口。

此适用于Express版本4.13.1。


4

针对Mac OS X和Linux用户的提示:

如果您想在小于1024的端口上运行您的Node / Express应用程序,则必须以超级用户身份运行: sudo PORT=80 node app.js


3
在端口号低于1024的情况下运行您的应用程序的更好选择是将一个具有较高编号的端口进行转发。通常被认为是不良实践的做法是使用sudo来访问低于1024的端口号。 - Pieter VDE

4
在最新的express-generator(4.13.1)版本中,app.js是一个导出的模块,并且服务器在/bin/www中启动。在app.js中使用app.set('port', process.env.PORT || 3001)来启动服务器将被/bin/www中类似的语句覆盖。我只是更改了bin/www中的语句。

3
在 app.js 中,只需添加...
process.env.PORT=2999;

这将把PORT变量隔离到express应用程序中。

2

如果你想展示你连接在 3000 上的东西

var express = require('express')
var app = express()

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.listen(3000, function () {
  console.log('Example app listening on port 3000!')
})

希望这对你有所帮助


2

你找到的这行代码是查找环境变量PORT,如果定义了它就使用它,否则使用默认端口3000。你需要先定义这个环境变量(不需要root权限)。

export PORT=8080
node <your-app.js>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接