NodeJS:如何获取服务器的端口?

175

在 Node.js 的示例“Hello World”代码中,通常会创建一个 HTTP 服务器并开始侦听端口,然后跟着一些类似以下的内容:

console.log('Server is listening on port 8000');

但是最好的情况应该是这样:

console.log('Server is listening on port ' + server.port);

如何在调用server.listen()之前检索服务器当前正在侦听的端口,而无需将该数字存储在变量中?

我以前见过这样做,但在Node文档中找不到它。也许这是特定于express的某些东西?


3
req.headers.host 中查找。 - Andrew_1510
19个回答

198

Express 4.x 的答案:

根据 Tien Do 在下面的回答中所说,Express 4.x 现在将 app.listen() 视为异步操作,因此 listener.address() 只会在 app.listen() 的回调函数内返回数据:

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

var listener = app.listen(8888, function(){
    console.log('Listening on port ' + listener.address().port); //Listening on port 8888
});

Express 3的解答:

我认为你正在寻找这个(特定于express的):

console.log("Express server listening on port %d", app.address().port)

当你使用express命令创建目录结构时,你可能会看到这个(底部的那一行):

alfred@alfred-laptop:~/node$ express test4
   create : test4
   create : test4/app.js
   create : test4/public/images
   create : test4/public/javascripts
   create : test4/logs
   create : test4/pids
   create : test4/public/stylesheets
   create : test4/public/stylesheets/style.less
   create : test4/views/partials
   create : test4/views/layout.jade
   create : test4/views/index.jade
   create : test4/test
   create : test4/test/app.test.js
alfred@alfred-laptop:~/node$ cat test4/app.js 

/**
 * Module dependencies.
 */

var express = require('express');

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.use(express.bodyDecoder());
  app.use(express.methodOverride());
  app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
  app.use(app.router);
  app.use(express.staticProvider(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
});

app.configure('production', function(){
  app.use(express.errorHandler()); 
});

// Routes

app.get('/', function(req, res){
  res.render('index.jade', {
    locals: {
        title: 'Express'
    }
  });
});

// Only listen on $ node app.js

if (!module.parent) {
  app.listen(3000);
  console.log("Express server listening on port %d", app.address().port)
}

1
谢谢,我认为这正是我正在寻找的。一旦我有机会测试它,我会接受它。干杯。 - David Tang
9
如果您不想使用变量 var listener,您可以在 app.listen() 的回调函数中使用 this.address().port - Andrei Stalbe
1
在 Express 5.x 中,这是什么样子的? - Diogenes
3
您还可以在中间件的任何地方获取端口号:req.socket.address().port - jlguenego
1
只是为了补充@AndreiStalbe所说的,您可以使用this.address.port(),但您不能在箭头函数内部使用它。 您需要使用老式的app.listen(8000, function () { console.log('http://localhost:' + this.address().port); }(是的,我知道反引号更好,但我无法在堆栈溢出评论中使用它们) - WORMSS
async 函数内部运行时,listener.address 无法工作,原因不确定。Express 版本为 4.17.1,Node 版本为 v14.17.0。 - Ciro Santilli OurBigBook.com

68
在 Express v3.0 中,
/* No longer valid */
var app = express.createServer();
app.listen();
console.log('Server running on %s', app.address().port);

不再起作用!对于Express v3.0,您应该按照以下方式创建一个应用程序和服务器:

var express = require('express');
var http = require('http');

var app = express();
var server = http.createServer(app);

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

server.listen(3000);
console.log('Express server started on port %s', server.address().port);

我自己遇到了这个问题,并想记录一下新的语法。Express v3.0 中的这些和其他更改可以在 https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x 中查看。


或者你可以继续使用旧的创建服务器的方法,它仍然有效。只是似乎不再有一种方法在之后访问端口。但是,由于您在调用server.listen时自己指定了端口,因此实际上没有必要使用server.address().port,因为您可以直接使用传递给server.listen的相同值。 - Mary Hamlin
(虽然我刚刚阅读了迁移指南,并看到您上面提到的创建应用程序和服务器的方法实际上是新的首选方法。) - Mary Hamlin
3
如果你在调用 server.listen() 时传递了参数 0,则以下信息会很有用:此时会自动分配一个随机端口号。如果你想在同一台服务器上运行多个 Express 应用程序,且不希望手动分配端口号,则可以采用这种方式。 - Nate
app.listen() 也会返回 HTTP 服务器实例。 - Vicary

33

如果在请求处理时需要一个端口,但应用程序不可用,则可以使用以下方法:

request.socket.localPort

这就是答案! :) - KARASZI István

28
在当前版本(v0.5.0-pre)中,端口似乎作为服务器对象的一个属性可用,请参见http://nodejs.org/docs/v0.4.7/api/net.html#server.address
var server = http.createServer(function(req, res) {
    ...
}

server.listen(8088);
console.log(server.address());
console.log(server.address().address);
console.log(server.address().port);

输出

{ address: '0.0.0.0', port: 8088 }
0.0.0.0
8088

25

我使用 Express 4 的这种方式:

app.listen(1337, function(){
  console.log('Express listening on port', this.address().port);
});

使用这个方法,我不需要为监听器/服务器使用单独的变量。


5
到目前为止最好的答案!如果您正在使用ES6,请不要使用箭头函数。this将是未定义的。 - Laxmana
这个代码可以在 async 函数内部工作,而 listener.address().port 的方法则不行。 - Ciro Santilli OurBigBook.com

17

如果你在使用express,你可以从请求对象中获取它:

req.app.settings.port // => 8080 or whatever your app is listening at.

11

导入http模块从未是必要的。

在Express 3或4中,不需要额外导入http模块。只需分配listen()的结果即可。

var server = require('express')();

server.get('/', function(req, res) {
  res.send("Hello Foo!");
});

var listener = server.listen(3000);
console.log('Your friendly Express server, listening on port %s', listener.address().port);
// Your friendly Express server, listening on port 3000

再次强调,这是在 Express 3.5.1 & 4.0.0 版本中测试的。导入 http 模块从来都不是必要的。listen 方法返回一个 http 服务器对象。 https://github.com/visionmedia/express/blob/master/lib/application.js#L531


8
req.headers.host.split(':')[1]

8

如果您没有定义端口号,但是想知道它正在哪个端口上运行。

let http = require('http');
let _http = http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello..!')
}).listen();
console.log(_http.address().port);

提醒您,每次运行时都会使用不同的端口。


7
您可以通过以下代码使用server.address().port获得端口号:
var http = require('http');
var serverFunction = function (req, res) {

    if (req.url == '/') {
        console.log('get method');
        res.writeHead(200, { 'content-type': 'text/plain' });
        res.end('Hello World');
    }

}
var server = http.createServer(serverFunction);
server.listen(3002, function () {
    console.log('server is listening on port:', server.address().port);
});

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