⭐️ 更多前端技术和知识点,搜索订阅号
JS 菌
订阅
二进制传输
(分片方式不一样,HTTP2 以前是字符串的形式发送)不按照顺序
发送头信息压缩
以及 Server Push(服务端主动推送内容)等高效率的功能使用 HTTP2 的好处这里再也不赘述了,网上一大堆材料本身查 😆html
这篇短文简单介绍一下如何在 node 应用中使用 http2:前端
openssl genrsa -des3 -out server.key 2048
node
上述命令使用 Triple-DES 算法生成私钥 server.keynginx
# 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 ...
实际上就是长这样的一串文本git
用来给证书颁发机构使用其根证书私钥签名生成证书公钥的东西
使用以下命令生成 CSR:github
openssl req -new -key server.key -out server.csr
算法
须要使用上一个步骤生成的 server 私钥来建立一个 csr 证书签名请求文件express
注意这里还须要输入生成私钥时候设置的密码 pass
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
会询问一系列问题 所有默认为空是不行的 你必须得填点东西 😵apache
# 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
长这样浏览器
为啥要删除看这里: https://blog.longwin.com.tw/2014/08/apache2-nginx-ssl-restart-auto-input-password-2014/
cp server.key server.pass.key openssl rsa -in server.pass.key -out server.key
这样就将密码移除了
最后就要生成自签名证书了,须要使用证书签名请求文件 server.csr 和私钥 server.key,有效期一年:
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
最后删掉 server.pass.key 便可(没有密钥留着会有危险)
生成的文件在某个文件夹内,在须要的时候读取便可:
. ├── server.crt └── server.key
// 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 命令访问:
curl https://localhost:3000/ --insecure curl: (56) LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 54
RangeError: Invalid typed array length: -4095
😐
竟然报错,网上搜了一下发现是 node 版本问题:
https://github.com/spdy-http2/node-spdy/issues/350
尝试切换 node 版本到 v10:
node -v v10.15.3
再次启动:
[nodemon] 1.18.11 [nodemon] to restart at any time, enter `rs` [nodemon] watching: *.* [nodemon] starting `node app.js` Listening at: 3000.
用浏览器访问:
protocol: h2 ~ 🚀
h2 的一大特点是服务端推的能力,使用 spdy 这个模块能轻松实现这个功能:
在项目目录里新建一个图片,咱们准备使用 push 将图片等静态资源推送到客户端
修改 APP 代码以下:
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
修改代码:
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
参考:
请关注个人订阅号,不按期推送有关 JS 的技术文章,只谈技术不谈八卦 😊