详解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 相关文章推荐
addRule在firefox下的兼容写法
Nov 30 Javascript
JavaScript 特殊字符
Apr 05 Javascript
JavaScript表单常用验证集合
Jan 16 Javascript
用JSON做数据传输格式中的一些问题总结
Dec 21 Javascript
js用闭包遍历树状数组的方法
Mar 19 Javascript
基于JavaScript实现Json数据根据某个字段进行排序
Nov 24 Javascript
vue 中filter的多种用法
Apr 26 Javascript
如何基于filter实现网站整体变灰功能
Apr 17 Javascript
解决vuex数据页面刷新后初始化操作
Jul 26 Javascript
vue element和nuxt的使用技巧分享
Jan 14 Vue.js
原生js实现自定义难度的扫雷游戏
Jan 22 Javascript
小程序实现侧滑删除功能
Jun 25 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
将RTF格式的文件转成HTML并在网页中显示的代码
2006/10/09 PHP
比较好用的PHP防注入漏洞过滤函数代码
2012/04/11 PHP
ThinkPHP 404页面的设置方法
2015/01/14 PHP
Laravel框架搜索分页功能示例
2019/02/01 PHP
ext监听事件方法[初级篇]
2008/04/27 Javascript
prototype 学习笔记整理
2009/07/17 Javascript
JavaScript中json对象和string对象之间相互转化
2012/12/26 Javascript
使用js解决由border属性引起的div宽度问题
2013/11/26 Javascript
js/jquery解析json和数组格式的方法详解
2014/01/09 Javascript
jQuery控制TR显示隐藏的几种方法
2014/06/18 Javascript
JavaScript遍历table表格中的某行某列并打印其值
2014/07/08 Javascript
JavaScript Math.ceil 方法(对数值向上取整)
2015/01/09 Javascript
cookie的secure属性详解
2015/04/08 Javascript
JS实现的新浪微博大厅文字内容滚动效果代码
2015/11/05 Javascript
bootstrap表单示例代码分享
2017/05/18 Javascript
原生JS实现瀑布流插件
2018/02/06 Javascript
Angularjs实现数组随机排序的方法
2018/10/02 Javascript
原生js实现公告滚动效果
2021/01/10 Javascript
Vue项目中如何使用Axios封装http请求详解
2019/10/23 Javascript
H5实现手机拍照和选择上传功能
2019/12/18 Javascript
原生javascript制作贪吃蛇小游戏的方法分析
2020/02/26 Javascript
跟老齐学Python之使用Python查询更新数据库
2014/11/25 Python
Django中URLconf和include()的协同工作方法
2015/07/20 Python
python django 实现验证码的功能实例代码
2017/05/18 Python
pytorch 实现tensor与numpy数组转换
2019/12/27 Python
python和pywin32实现窗口查找、遍历和点击的示例代码
2020/04/01 Python
python使用OpenCV模块实现图像的融合示例代码
2020/04/10 Python
乌克兰香水和化妆品网站:Notino.ua
2018/03/26 全球购物
开业典礼主持词
2014/03/21 职场文书
幼儿园小班见习报告
2014/10/31 职场文书
幼儿园教师安全责任书
2015/05/08 职场文书
放牛班的春天观后感
2015/06/01 职场文书
导游词之山西关帝庙
2019/11/01 职场文书
如何用PHP websocket实现网页实时聊天
2021/05/26 PHP
CSS实现五种常用的2D转换
2021/12/06 HTML / CSS
django中websocket的具体使用
2022/01/22 Python