Express.js - app.listen与server.listen的区别

645

这可能是一个非常基础的问题,但我不明白其中的区别。使用Express.js创建应用程序与例如在端口1234上启动应用程序有何区别:

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

//app.configure, app.use etc

app.listen(1234);

并添加一个HTTP服务器:

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

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

//app.configure, app.use etc

server.listen(1234);

有什么区别?
如果我导航到http://localhost:1234,那么我会得到相同的输出。


7
我知道这个问题旧了,但我想指出,createServer已经被弃用了。 - Philip Kirkbride
2
@PhilipKirkbride,您能否提供证明? - yanot
31
我相信这是一个有些误导性的说法。ExpressJS 的 createServer() 方法已被弃用,但 Node.js 的 HTTP 模块仍在使用 createServer(),并且这个方法没有被弃用。 - Tamas
6个回答

766

如果您想重复使用HTTP服务器,例如在同一HTTP服务器实例中运行socket.io,则第二种形式(自己创建HTTP服务器而不是让Express为您创建)非常有用:

var express = require('express');
var app     = express();
var server  = require('http').createServer(app);
var io      = require('socket.io').listen(server);
...
server.listen(1234);

然而,app.listen()也会返回HTTP服务器实例,因此通过一些重写,您可以在不创建HTTP服务器的情况下实现类似的功能:

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

// app.use/routes/etc...

var server    = app.listen(3033);
var io        = require('socket.io').listen(server);

io.sockets.on('connection', function (socket) {
  ...
});

4
require('http').createServer(require('express')).listen(80) 与 require("express")().listen(80) 意思相同吗? - user2167582
14
@user2167582 效果是一样的,但当然字面上的 === 比较会失败 ;) 如果你不相信我,源代码在这里 - robertklep
10
问题并不涉及到插座,但这正是我来这里的原因。 - anthonygore
5
我几乎总是使用app.listen(),因为它需要的代码更少。由于它只是在server.listen()之上添加了一个非常薄的层,并且返回服务器实例,通常没有必要手动创建单独的HTTP服务器实例。 - robertklep
2
@Reine_Ran_ 基本上是这样的。app.listen()(Express)将创建一个常规的HTTP服务器(使用http.createServer());如果您想在HTTPS上运行Express,则需要单独使用https.createServer()并将Express“附加”到它上面(或者使用像nginx这样的单独的HTTPS服务器作为HTTPS终止器)。 - robertklep
显示剩余10条评论

86

使用应用程序和监听HTTP服务器的另一个区别在于当您想要设置HTTPS服务器时

为了设置HTTPS,您需要以下代码:

var https = require('https');
var server = https.createServer(app).listen(config.port, function() {
    console.log('Https App started');
});

从express中使用的应用程序只会返回HTTP服务器,您无法在express中进行设置,因此您需要使用HTTPS服务器命令。

var express = require('express');
var app = express();
app.listen(1234);

65

官方文档中了解到:

由express()返回的应用程序实际上是JavaScript函数, 旨在作为回调传递给Node的HTTP服务器,以处理请求。

这使得您可以使用相同的代码库提供HTTP和HTTPS版本的应用程序,因为该应用程序不继承它们(它只是一个回调函数):

var https =require('https');
var http = require('http');
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);

app.listen()方法返回一个http.Server对象,对于HTTP而言,它是一个便利方法,其等价于以下代码:

app.listen = function() {
  var server = http.createServer(this);
  return server.listen.apply(server, arguments);
};

5
请简要解释第二段代码。这里的"convenience method"具体是什么意思? - Aakash Verma
2
@AakashVerma 这只是 Express 源代码的一部分,可以在 express/lib/application.js 中找到,它只是一个创建 Node HTTP 服务器的快捷方式,没有其他内容。 - Ivan Talalaev
那么你的意思是说,当我们使用app by express()作为回调函数时,它会接收来自外部HTTP服务器(通过80或443端口)的请求,然后在自身内部创建另一个虚拟服务器http.Server,并使用它来监听转发给它的请求? - Aakash Verma
var https = require('https'); var http = require('http'); - Shalabyer

16

我有同样的问题,但在谷歌搜索后,发现没有太大的区别 :)

来自Github

如果您希望创建HTTP和HTTPS服务器,可以使用“http”和“https”模块,如下所示。

/**
 * Listen for connections.
 *
 * A node `http.Server` is returned, with this
 * application (which is a `Function`) as its
 * callback. If you wish to create both an HTTP
 * and HTTPS server you may do so with the "http"
 * and "https" modules as shown here:
 *
 *    var http = require('http')
 *      , https = require('https')
 *      , express = require('express')
 *      , app = express();
 *
 *    http.createServer(app).listen(80);
 *    https.createServer({ ... }, app).listen(443);
 *
 * @return {http.Server}
 * @api public
 */

app.listen = function(){
  var server = http.createServer(this);
  return server.listen.apply(server, arguments);
};

另外,如果你想使用socket.io进行工作,请查看他们的示例

参见此处

我更喜欢app.listen() :)


13

Express基本上是http模块的包装器,旨在为开发人员提供便利,使他们可以:

  1. 使用express轻松设置中间件以响应HTTP请求。
  2. 通过向模板传递参数,使用express动态呈现HTML页面。
  3. 还可以使用express轻松定义路由。

-1
http模块不再需要,除非你需要直接与其一起工作(socket.io/SPDY/HTTPS)。可以使用app.listen()函数启动应用程序。

expressjs.com


https://meta.stackoverflow.com/a/285557/11107541, /help/formatting, /help/referencing. - starball

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