前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何创建 http2 node App

如何创建 http2 node App

作者头像
JS菌
发布2019-07-23 11:27:10
9080
发布2019-07-23 11:27:10
举报
文章被收录于专栏:JS菌JS菌

如何创建 http2 node App

⭐️ 更多前端技术和知识点,搜索订阅号 JS 菌 订阅

  • 所有数据以二进制传输(分片方式不同,HTTP2 之前是字符串的形式发送)
  • 发送的请求可以不按照顺序发送
  • 头信息压缩以及 Server Push(服务端主动推送内容)等高效率的功能
  • 信道复用(只需要建立一个 TCP 链接)
  • 分帧传输(并发发送不同请求)

使用 HTTP2 的好处这里不再赘述了,网上一大堆材料自己查 ?

这篇短文简单介绍一下如何在 node 应用中使用 http2:

  • 首先需要 SSL 证书
  • 创建服务端 APP
  • 以 express 为例安装 spdy 模块

自签名 SSL 证书

生成私钥 Key

openssl genrsa -des3 -out server.key 2048

上述命令使用 Triple-DES 算法生成私钥 server.key

代码语言:javascript
复制
# cat server.key 

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,EB5B873BE89A5456

GWpEoVlP7DA9S955gUVZgrWww+PTspxwFMEoUKN9Z0WgjR30Qa+OOC93eyeVw/Zz
UvE60mCocTP0iSOOUCobW9i/v012zH6//QngqfzahVqqCz5B3zOAaB+LKOj/1S9X
GL7P7OOGWXik4nCGoN1rGszK6TqtboAl4YM00si/bU0wgrCxdCLV4ISvtMFV1cLz
4I0E9fbJI3MBZWlgTlm1RlOo0vyUFjmPJm78qLJlyD7Mk4VZ7uBh973UArkYpZNt
8hCtwj+DoPRUo/lXsoH4J/W3ma7BlrEjg7PkKffnX/L6HTqPMWV2zK6mmeiBoSdH
zL+rc7V8mqntrsZ+6qkNbjOV27zBi47SdDPP8CRnsggO83U/yJsxgruDzs7/f1sM
...

实际上就是长这样的一串文本

生成证书签名请求文件 CSR

用来给证书颁发机构使用其根证书私钥签名生成证书公钥的东西

使用如下命令生成 CSR:

openssl req -new -key server.key -out server.csr

需要使用上一个步骤生成的 server 私钥来创建一个 csr 证书签名请求文件

注意这里还需要输入生成私钥时候设置的密码 pass

代码语言:javascript
复制
Country Name (2 letter code) []:
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:
Email Address []:
error, no objects specified in config file
problems making Certificate Request

会询问一系列问题 全部默认为空是不行的 你必须得填点东西 ?

代码语言:javascript
复制
# cat server.csr

-----BEGIN CERTIFICATE REQUEST-----
MIIC6DCCAdACAQAwgYkxCzAJBgNVBAYTAkNOMRIwEAYDVQQIDAlndWFuZ2Rvbmcx
ETAPBgNVBAcMCHNoZW56aGVuMRAwDgYDVQQKDAd0ZW5jZW50MRAwDgYDVQQLDAdz
ZWN0aW9uMRAwDgYDVQQDDAdUZW5jZW50MR0wGwYJKoZIhvcNAQkBFg50ZXN0QGdt
YWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALEcfCsfSxg9
Rc20riGI7j06u3kt5A9+s/RUWYjFMuh9oXpl7njUrZX6rdxA0Ckl+X/9JHjGmYpX
EO23hVCSfyK9fpMd9MiPs5CvFkll3GH7xomif1aRv/ZXkyvTSBpCjRdemysqRy8Y
i+3N8l0qnxIJ5A4LbV4QhjVL+4iv/0Y4zvvjuOY7Rvtm4vU1YiKCS2T6NdJ46Msu
ZRvm8VtKqWtjk1ZM+0iFE8rRFJZ1Jepj+5vtqcqz1s0gKpwZ+jFIhzieGXTuKsp0

长这样

删除掉私钥中的密码短语 passphrase

为啥要删除看这里:https://blog.longwin.com.tw/2014/08/apache2-nginx-ssl-restart-auto-input-password-2014/

代码语言:javascript
复制
cp server.key server.pass.key
openssl rsa -in server.pass.key -out server.key

这样就将密码移除了

生成自签名证书

最后就要生成自签名证书了,需要使用证书签名请求文件 server.csr 和私钥 server.key,有效期一年:

代码语言:javascript
复制
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

最后删掉 server.pass.key 即可(没有密钥留着会有危险)

生成的文件在某个文件夹内,在需要的时候读取即可:

代码语言:javascript
复制
.
├── server.crt
└── server.key

创建服务端 App

代码语言:javascript
复制
// app.js

const spdy = require("spdy");
const express = require("express");
const fs = require("fs");
const path = require("path");
const app = express();

app.get("/", function(req, res) {
  res.send("hello world");
});

const options = {
  key: fs.readFileSync(path.resolve(__dirname, "../cert/server.key")),
  cert: fs.readFileSync(path.resolve(__dirname, "../cert/server.crt"))
};

spdy.createServer(options, app).listen(3000, err => {
  if (err) { throw new Error(err) }

  console.log("Listening at: " + 3000);
});

然后 node app.js 运行,尝试使用 curl 命令访问:

代码语言:javascript
复制
curl https://localhost:3000/ --insecure
curl: (56) LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 54
代码语言:javascript
复制
RangeError: Invalid typed array length: -4095

?

居然报错,网上搜了一下发现是 node 版本问题:

https://github.com/spdy-http2/node-spdy/issues/350

尝试切换 node 版本到 v10:

代码语言:javascript
复制
node -v
v10.15.3

再次启动:

代码语言:javascript
复制
[nodemon] 1.18.11
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node app.js`
Listening at: 3000.

用浏览器访问:

protocol: h2 ~ ?

尝试服务端 push

h2 的一大特色是服务端推的能力,使用 spdy 这个模块能轻松实现这个功能:

在项目目录里新建一个图片,我们准备使用 push 将图片等静态资源推送到客户端

修改 APP 代码如下:

代码语言:javascript
复制
const spdy = require("spdy");
const express = require("express");
const fs = require("fs");
const path = require("path");
const app = express();

app.get("/app.js", (req, res) => {
  res.end(fs.readFileSync("./app.js"));
});

app.get("/", (req, res) => {
  res.push("/test.png", { method: "GET" }).end(fs.readFileSync("./test.png"));
  //   res.push("/app.js", { method: "GET" }).end(fs.readFileSync('./app.js'));

  res.end(`
<html>
<head>
<script src="/app.js"></script>
</head>
<body><img src="/test.png"></body>
</html>
  `);
});

const options = {
  key: fs.readFileSync(path.resolve(__dirname, "../cert/server.key")),
  cert: fs.readFileSync(path.resolve(__dirname, "../cert/server.crt"))
};

spdy.createServer(options, app).listen(3000, err => {
  if (err) {
    throw new Error(err);
  }

  console.log("Listening on port: " + 3000 + ".");
});

上面代码开启了 test.png 图片文件的 push,而未开启 js 文件的 push 效果如下:

图片确实使用了 push

修改代码:

代码语言:javascript
复制
app.get("/", (req, res) => {
  res.push("/test.png", { method: "GET" }).end(fs.readFileSync("./test.png"));
  res.push("/app.js", { method: "GET" }).end(fs.readFileSync("./app.js"));

  // ...

脚本文件也成功使用了 push:

done

参考:

  • https://www.akadia.com/services/ssh_test_certificate.html
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JS菌 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如何创建 http2 node App
    • 自签名 SSL 证书
      • 生成私钥 Key
      • 生成证书签名请求文件 CSR
      • 删除掉私钥中的密码短语 passphrase
      • 生成自签名证书
    • 创建服务端 App
      • 尝试服务端 push
相关产品与服务
SSL 证书
腾讯云 SSL 证书(SSL Certificates)为您提供 SSL 证书的申请、管理、部署等服务,为您提供一站式 HTTPS 解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档