详解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 相关文章推荐
javawscript 三级菜单的实现原理
Jul 01 Javascript
jQuery中hasClass()方法用法实例
Jan 06 Javascript
jQuery 跨域访问解决原理案例详解
Jul 09 Javascript
AngularJS延迟加载html template
Jul 27 Javascript
jQuery Easyui Tabs扩展根据自定义属性打开页签
Aug 15 Javascript
简单实现JS计算器功能
Dec 21 Javascript
JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
Jan 05 Javascript
javascript兼容性(实例讲解)
Aug 15 Javascript
JavaScript中立即执行函数实例详解
Nov 04 Javascript
nuxt框架中路由鉴权之Koa和Session的用法
May 09 Javascript
layui问题之模拟table表格中的选中按钮选中事件的方法
Sep 20 Javascript
vue form表单post请求结合Servlet实现文件上传功能
Jan 22 Vue.js
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保存任意网络图片到服务器的方法
2015/04/14 PHP
PHP使用ActiveMQ实现消息队列的方法详解
2019/05/31 PHP
php实现简单的守护进程创建、开启与关闭操作
2019/08/13 PHP
JQuery 学习笔记 选择器之三
2009/07/23 Javascript
jquery阻止后续事件只执行第一个事件
2014/07/24 Javascript
js实现完全自定义可带多级目录的网页鼠标右键菜单方法
2015/02/28 Javascript
Javascript6中字符串的四个新用法分享
2016/09/11 Javascript
jQuery中DOM节点的删除方法总结(超全面)
2017/01/22 Javascript
微信小程序实战之仿android fragment可滑动底部导航栏(4)
2020/04/16 Javascript
nodejs入门教程三:调用内部和外部方法示例
2017/04/24 NodeJs
详解vue 模版组件的三种用法
2017/07/21 Javascript
JS+H5 Canvas实现时钟效果
2018/07/20 Javascript
开发用到的js封装方法(20种)
2018/10/12 Javascript
跟混乱的页面弹窗说再见
2019/04/11 Javascript
微信小程序Echarts覆盖正常组件问题解决
2019/07/13 Javascript
Vue使用富文本编辑器Vue-Quill-Editor(含图片自定义上传服务、清除复制粘贴样式等)
2020/05/15 Javascript
微信小程序将页面按钮悬浮固定在底部的实现代码
2020/10/29 Javascript
一分钟学会JavaScript中的try-catch
2020/12/14 Javascript
[37:35]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第二局
2016/02/25 DOTA
在Python中使用M2Crypto模块实现AES加密的教程
2015/04/08 Python
Python实现方便使用的级联进度信息实例
2015/05/05 Python
python使用requests模块实现爬取电影天堂最新电影信息
2019/04/03 Python
Python中sorted()排序与字母大小写的问题
2020/01/14 Python
python range实例用法分享
2020/02/06 Python
python GUI库图形界面开发之PyQt5信号与槽基础使用方法与实例
2020/03/06 Python
Python基于xlutils修改表格内容过程解析
2020/07/28 Python
python接口自动化之ConfigParser配置文件的使用详解
2020/08/03 Python
python实现图片,视频人脸识别(opencv版)
2020/11/18 Python
荣耀俄罗斯官网:HONOR俄罗斯
2020/10/31 全球购物
经典c++面试题五
2014/12/17 面试题
EntityManager都有哪些方法
2013/11/01 面试题
自我鉴定200字
2013/10/28 职场文书
事务机电主管工作职责
2014/02/25 职场文书
大班开学家长寄语
2014/04/04 职场文书
大学生实习证明范文(5篇)
2014/09/18 职场文书
正则表达式拆分url实例代码
2022/02/24 Java/Android