如何建立 http2 node App

20190717234843.png

⭐️ 更多前端技術和知識點,搜索訂閱號 JS 菌 訂閱html

  • 全部數據以二進制傳輸(分片方式不一樣,HTTP2 以前是字符串的形式發送)
  • 發送的請求能夠不按照順序發送
  • 頭信息壓縮以及 Server Push(服務端主動推送內容)等高效率的功能
  • 信道複用(只須要創建一個 TCP 連接)
  • 分幀傳輸(併發發送不一樣請求)

使用 HTTP2 的好處這裏再也不贅述了,網上一大堆材料本身查 😆前端

這篇短文簡單介紹一下如何在 node 應用中使用 http2:node

  • 首先須要 SSL 證書
  • 建立服務端 APP
  • 以 express 爲例安裝 spdy 模塊

自簽名 SSL 證書

生成私鑰 Key

openssl genrsa -des3 -out server.key 2048nginx

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

# 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
...
複製代碼

實際上就是長這樣的一串文本github

生成證書籤名請求文件 CSR

用來給證書頒發機構使用其根證書私鑰簽名生成證書公鑰的東西算法

使用以下命令生成 CSR:express

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

須要使用上一個步驟生成的 server 私鑰來建立一個 csr 證書籤名請求文件瀏覽器

注意這裏還須要輸入生成私鑰時候設置的密碼 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
複製代碼

會詢問一系列問題 所有默認爲空是不行的 你必須得填點東西 😵

# 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

爲啥要刪除看這裏: blog.longwin.com.tw/2014/08/apa…

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

// 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 版本問題:

github.com/spdy-http2/…

嘗試切換 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.
複製代碼

用瀏覽器訪問:

20190717225740.png

protocol: h2 ~ 🚀

嘗試服務端 push

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 效果以下:

20190717233936.png

圖片確實使用了 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:

20190717234100.png

done

參考:

JS 菌公衆帳號

請關注個人訂閱號,不按期推送有關 JS 的技術文章,只談技術不談八卦 😊

相關文章
相關標籤/搜索