详解node如何让一个端口同时支持https与http


Posted in Javascript onJuly 04, 2017

众所周知node是一个高性能的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生成的每个服务器必须分配一个端口。那么如果我们在工作中遇到一个需求:让同一个端口或地址既支持http协议又支持https协议,这时候我们该怎么办,有的同学很可能想到用nginx做反向代理,这不失为一个解决方案,但这也同样意味着增加了产品的复杂度,用户并不想去折腾ngnix。

办法是有的,原理就要搬出OSI的七层模型:

详解node如何让一个端口同时支持https与http

HTTP与HTTPS都属于应用层协议,所以只要我们在底层协议中进行反向代理,就可以解决这个问题! 刚好node可以让我们很方便的创建一个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);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 对表格的行和列都能加亮显示
Dec 26 Javascript
Javascript中找到子元素在父元素内相对位置的代码
Jul 21 Javascript
纯js代码实现未知宽高的元素在指定元素中垂直水平居中显示
Sep 12 Javascript
基于JavaScript实现多级菜单效果
Jul 25 Javascript
全面解析jQuery中的$(window)与$(document)的用法区别
Aug 15 jQuery
Vue结合SignalR实现前后端实时消息同步
Sep 19 Javascript
JavaScript 隐性类型转换步骤浅析
Mar 15 Javascript
js动态引入的四种方法
May 05 Javascript
ES6 fetch函数与后台交互实现
Nov 14 Javascript
Vue实现导航栏点击当前标签变色功能
Aug 19 Javascript
ES6常用小技巧总结【去重、交换、合并、反转、迭代、计算等】
Dec 21 Javascript
微信小程序 button样式设置为图片的方法
Jun 19 Javascript
Angular 2父子组件之间共享服务通信的实现
Jul 04 #Javascript
jQuery实现动态给table赋值的方法示例
Jul 04 #jQuery
Angular 2父子组件数据传递之局部变量获取子组件其他成员
Jul 04 #Javascript
Angular 4.X开发实践中的踩坑小结
Jul 04 #Javascript
jQuery操作DOM_动力节点Java学院整理
Jul 04 #jQuery
jQuery层级选择器_动力节点节点Java学院整理
Jul 04 #jQuery
jQuery简介_动力节点Java学院整理
Jul 04 #jQuery
You might like
使用PHP提取视频网站页面中的FLASH地址的代码
2010/04/17 PHP
PHP 命令行工具 shell_exec, exec, passthru, system详细使用介绍
2011/09/11 PHP
php随机输出名人名言的代码
2012/10/07 PHP
关于Curl在Swoole协程中的解决方案详析
2019/09/12 PHP
JavaScript 学习 - 提高篇
2007/02/02 Javascript
通过正则格式化url查询字符串实现代码
2012/12/28 Javascript
node.js中的socket.io的广播消息
2014/12/15 Javascript
JS上传图片前实现图片预览效果的方法
2015/03/02 Javascript
javascript中in运算符用法分析
2015/04/28 Javascript
JS实现复制内容到剪贴板功能兼容所有浏览器(推荐)
2016/06/17 Javascript
JS常用倒计时代码实例总结
2017/02/07 Javascript
Node.js中你不可不精的Stream(流)
2018/06/08 Javascript
JS使用tween.js动画库实现轮播图并且有切换功能
2018/07/17 Javascript
video.js 实现视频只能后退不能快进的思路详解
2018/08/09 Javascript
vue中使用protobuf的过程记录
2018/10/26 Javascript
vscode配置vue下的es6规范自动格式化详解
2019/03/20 Javascript
如何通过setTimeout理解JS运行机制详解
2019/03/23 Javascript
微信小程序实现滚动加载更多的代码
2019/12/06 Javascript
django实现同一个ip十分钟内只能注册一次的实例
2017/11/03 Python
Python类和实例的属性机制原理详解
2020/03/21 Python
python实现将range()函数生成的数字存储在一个列表中
2020/04/02 Python
使用PyQt的QLabel组件实现选定目标框功能的方法示例
2020/05/19 Python
Python基于字典实现switch case函数调用
2020/07/22 Python
python中如何使用虚拟环境
2020/10/14 Python
爱他美官方海外旗舰店:Aptamil奶粉
2017/12/22 全球购物
英国女士和男士时尚服装网上购物:Top Labels Online
2018/03/25 全球购物
香港交友网站:be2香港
2018/07/22 全球购物
DJI大疆德国官方商城:大疆无人机
2018/09/01 全球购物
一篇.NET面试题
2014/09/29 面试题
什么是makefile? 如何编写makefile?
2012/08/08 面试题
化学学院毕业生自荐信范文
2013/12/17 职场文书
大三学生入党思想汇报
2014/01/02 职场文书
小学生国旗下演讲稿
2014/04/25 职场文书
2016三八妇女节慰问信
2015/11/30 职场文书
吃通javascript正则表达式
2021/04/21 Javascript
浅析Python实现DFA算法
2021/06/26 Python