Node.js 实现单端口同时支持 HTTP 与 HTTPS 的方案

作者:慢半拍

时间:2026-10-22

浏览:246

本文介绍如何在 Node.js 中让一个端口同时处理 HTTP 和 HTTPS 请求。通过基于 OSI 模型在 TCP 层进行协议识别与反向代理,利用 net 模块创建 TCP 服务器,根据请求头判断协议类型并转发至对应的 HTTP 或 HTTPS 服务器,从而避免使用 Nginx 增加系统复杂度。

文章目录

Node.js 单端口支持 HTTP 与 HTTPS 方案

Node.js 作为高性能 Web 服务器,能够轻松创建 HTTP 或 HTTPS 服务。

例如,一个简单的 HTTP 服务器实现如下:


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

var httpPort = 3345;

var server = http.createServer(function(req, res){
 res.writeHead(200, {'Content-Type': 'text/plain'});
 res.end('hello world!');
}).listen(httpPort);

HTTPS 服务器需生成证书,具体步骤可参考《HTTPS 的原理和 NodeJS 的实现》一文。此处直接展示最终成果,证书文件见附件。


var https = require('https');
var fs = require('fs');

var httpsPort = 3346;

var options = {
 key: fs.readFileSync('./cakey.pem'),
 cert: fs.readFileSync('./cacert.pem')
};

var sserver = https.createServer(options, function(req, res){
 res.writeHead(200, {'Content-Type': 'text/plain'});
 res.end('secured hello world');
}).listen(httpsPort);

由上述示例可知,Node.js 生成的每个服务器实例必须绑定特定端口。若业务需求要求同一端口或地址同时支持 HTTP 和 HTTPS 协议,常规思路是使用 Nginx 进行反向代理。此方案虽可行,但会增加产品部署的复杂度,并非所有用户都愿意引入 Nginx。

存在更优解决方案,其原理基于 OSI 七层网络模型:

Node.js 单端口支持 HTTP 与 HTTPS 方案

HTTP 与 HTTPS 均属于应用层协议。因此,只要我们在 在底层协议中进行反向代理,即可解决该问题。Node.js 提供了便捷的 TCP 服务器创建方式,恰好适用于此场景。

核心代码实现如下:


var net = require('net');
var http = require('http');
var https = require('https');
var fs = require('fs');

var httpPort = 3345;
var httpsPort = 3346;

var server = http.createServer(function(req, res){
 res.writeHead(200, {'Content-Type': 'text/plain'});
 res.end('hello world!');
}).listen(httpPort);

var options = {
 key: fs.readFileSync('./cakey.pem'),
 cert: fs.readFileSync('./cacert.pem')
};

var sserver = https.createServer(options, function(req, res){
 res.writeHead(200, {'Content-Type': 'text/plain'});
 res.end('secured hello world');
}).listen(httpsPort);

net.createServer(function(socket){
 socket.once('data', function(buf){
  console.log(buf[0]);
  // https数据流的第一位是十六进制“16”,转换成十进制就是22
  var address = buf[0] === 22 ? httpsPort : httpPort;
  //创建一个指向https或http服务器的链接
  var proxy = net.createConnection(address, function() {
   proxy.write(buf);
   //反向代理的过程,tcp接受的数据交给代理链接,代理链接服务器端返回数据交由socket返回给客户端
   socket.pipe(proxy).pipe(socket);
  });
  
  
  proxy.on('error', function(err) {
   console.log(err);
  });
 });
 
 socket.on('error', function(err) {
  console.log(err);
 });
}).listen(3344);

以上为本文全部内容,希望对读者学习有所帮助,欢迎支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章