我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

nodejs的网站后端领域里面,express框架可能是入门必备的框架。单独的express就是可以运行的,但是,为啥有的例子里面,会出现和nodejs内置的http/https合用的场景呢?要知道,某种意义上来说,expresshttp模块解决的是同样的事情。

苏南大叔:express框架, 为什么会混合使用内置的 http(s) 模块? - express-http-https
express框架, 为什么会混合使用内置的 http(s) 模块?(图6-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:win10nodejs@20.18.0express@4.21.2。本文试图解决一个疑惑,有关expresshttp合用的合理性问题。

express单独用例

参考代码如下:

var express = require("express");
var app = express();
app.use(express.static('public'));
app.use((request, response, next) => {
    console.log(request.method + " " + request.url);
    next();
});
app.get("*", (request, response, next) => {
    response.end(request.url);
});
app.listen(80, function () { console.log('http://localhost:%s', this.address().port) });

苏南大叔:express框架, 为什么会混合使用内置的 http(s) 模块? - express代码
express框架, 为什么会混合使用内置的 http(s) 模块?(图6-2)

本文并不是解释express的具体使用情况的,所以,更多使用方法可以参考下面的文章:

http模块单独用例

var http = require("http");
var app = http.createServer(function (request, response) {
    console.log(request.method + " " + request.url);
    response.writeHead(200, { "Content-Type": "text/plain" });
    response.end(request.url);
});
app.listen(80, () => console.log('http://localhost:%s', app.address().port));

苏南大叔:express框架, 为什么会混合使用内置的 http(s) 模块? - http代码
express框架, 为什么会混合使用内置的 http(s) 模块?(图6-3)

express和http模块合用例子

既生瑜何生亮?为啥两者要合用?那是因为:express框架本来就是基于http模块的,两者本身也没有太明显的竞争关系。

let express = require("express");
let _express = express();
_express.use(express.static('public'));
_express.use((request, response, next) => {
    console.log(request.method + " " + request.url);
    next();
});
_express.get("*", (request, response, next) => {
    response.end(request.url);
});
// _express.listen(80, function(){console.log('http://localhost:%s', this.address().port)});
let http = require("http");
let httpServer = http.createServer(_express);
httpServer.listen(80, () => console.log('http://localhost:%s', httpServer.address().port));

还可以开两个端口,

// ...
_express.listen(80, function(){console.log('http://localhost:%s', this.address().port)});
// ...
httpServer.listen(81, () => console.log('http://localhost:%s', httpServer.address().port));

本来express就可以.listen(),为啥非要使用http.createServer().listen()包装一下呢?

苏南大叔:express框架, 为什么会混合使用内置的 http(s) 模块? - 源码线索
express框架, 为什么会混合使用内置的 http(s) 模块?(图6-4)

express源码

点开express.listen()express的源码。就可以看到express官方推荐使用http或者https模块的注释。不过是个interface,通过关键字找到实现代码的话,就可以看到express.listen()的实现代码:

/**
 * 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}
 * @public
 */

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

苏南大叔:express框架, 为什么会混合使用内置的 http(s) 模块? - express-listen-code
express框架, 为什么会混合使用内置的 http(s) 模块?(图6-5)

所以,你所疑惑的代码,其实只是一个变换的写法罢了。expresslisten()方法,本来也调用的是http模块。那么,这样来说,两者的合用代码,就显得不那么奇怪了。

express 合用 http 和 https

新的监听三个端口的完整代码:

let express = require("express");
let _express = express();
_express.use(express.static('public'));
_express.use((request, response, next) => {
    console.log(request.method + " " + request.url);
    next();
});
_express.get("*", (request, response, next) => {
    response.end(request.url);
});
_express.listen(80, function () { console.log('http://localhost:%s', this.address().port) });
let http = require("http");
let httpServer = http.createServer(_express);
httpServer.listen(81, () => console.log('http://localhost:%s', httpServer.address().port));
let https = require('https');
let fs = require('fs');
let httpsServer = https.createServer({
    key: fs.readFileSync('./cert/cert-key.pem'),
    cert: fs.readFileSync('./cert/cert.pem')
}, _express);
httpsServer.listen(82, () => console.log('https://localhost:%s', httpsServer.address().port));

苏南大叔:express框架, 为什么会混合使用内置的 http(s) 模块? - 监控三个端口
express框架, 为什么会混合使用内置的 http(s) 模块?(图6-6)

结语

所以,结论是:expresshttp模块的关系,并不是对立,而是amigo的关系。

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   node    express