[译] Node.js, Express.js 搭建 HTTP/2 服务器

原文:Easy HTTP/2 Server with Node.js and Express.js
做者:Azat Mardan
代码:http2-express前端


什么是 HTTP/2

现代互联网的 TCP/IP 协议发布于1975年,这项技术在41年前是多么使人惊讶。自它发布开始大部分形式,咱们使用 HTTP 和 后续接任者 HTTP/1.1 来实现客户端和服务端的通信。它能很不错的传输 Web,但今时今日的开发者创建网站的方式已经发生了巨大的改变。存在各式各样的外部资源连接例如图片、CSS 文件、JavaScript 资源。资源的种类数量只会持续增加。node

HTTP/2 是针对表现一直不错的旧协议 HTTP 自从1991年发布以来这15年的第一次大的升级改动!它为优化现代浏览器而生。性能更加优越并且不用使用复杂的行为例如域名分片(经过多个域名发送资源)或者资源文件合并`(提供一个整合的大资源而不是多个小资源)git

HTTP/2 是当前 web 的新标准,其雏形是 Google 的 SPDY 协议。当前已经被大多数主流浏览器支持,且不少网站已经经过该协议实现。例如访问 Yahoo 的 Flickr 在使用的是 HTTP/2 协议(截图时间为2016年7月).github

Yahoo 的 Flickr 已经在使用 codeHTTP/2/code 协议

HTTP/2 的优点和注意事项

HTTP/2HTTP/1.1 的使用没什么区别,仍然能够在 body 中使用类 xml 的语法,使用 header 协议头字段, 状态码, cookies, methods, URLs, 等等。开发者熟悉使用的东西都还能够继续在 HTTP/2 使用。web

HTTP/2的优点以下:express

  1. 多路复用传输(Multiplexing):容许浏览器在单个TCP链接中包含多个请求,从而使浏览器可以并行地请求全部的资源;npm

  2. 服务器推送(Server push):服务器能够在浏览器知道须要该资源前,推送给浏览器(如:CSS、JS、Image),从而经过减小请求数量来加速页面加载时间;json

  3. 流传输优先级(Stream priority):容许浏览器去控制资源的加载优先级,例如,浏览器先请求 HTML 渲染再去加载其余的 CSSJS 文件;浏览器

  4. 头部压缩(Header compression): HTTP/1.1 请求的头部老是重复同样的内容,而 HTTP/2 则强制对全部请求的头部进行了去重压缩;缓存

  5. 实际的强制加密(De facto mandatory encryption):虽然加密不是硬性要求的,可是大多数浏览器只支持 TLS(HTTPS) 上的 HTTP/2

虽然目前对于 HTTP/2 还不能彻底知足一些苛求,可是直到更好的技术出现之前,当前是一项明显的技术进步。让咱们来看看,做为 Web 开发者须要了解的必要知识。大部分适用于 HTTP/1.1 的优化技巧在 HTTP/2 中变成多余的,其中一些甚至反而会影响 HTTP/2 上的网站性能,例如:

  1. 资源文件合并;

  2. 你也应该中止使用精灵图(image sprites)、CSS和JS打包,由于只要其中一小部分有改动就会影响客户端的缓存的做用;在 HTTP/2 协议上更好的方式是使用多个的小文件,而不是一个大文件。

  3. 做者但愿前端构建工具,如 GruntGulpWebpack 将会所以特性被放弃使用,他们使 Web 开发更高的复杂度,极高的学习曲线,以及管理项目的依赖关系。

  4. 另外一个适用于 HTTP/1.1 不适用于 HTTP/2 的是,域名分片(为了绕过TCP并行请求数量限制)。虽然它不必定在全部状况下有害,但对于 HTTP/2 的多路复用传输,这样作也已经没好处了。之因此建议不在 HTTP/2 使用域名分片,还由于每一个域名会带来额外的查询负载。若是真的有须要,那么更好的方式是解析多个域名到同一个IP,并且保证你使用的是通配符证书或整合了多域名的证书,从而减小域名查询的时间。

若想了解更多关于 HTTP/2 的介绍,能够看看官网

Node.js 搭建 HTTP/2

如今,让咱们看看怎么经过 Node.js 搭建 HTTP/2 服务器。

部署证书

建立一个新文件夹以及本身签发的 SSL 证书。

$ mkdir http2-express 
$ cd http2-express
$ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048
...
$ openssl rsa -passin pass:x -in server.pass.key -out server.key
writing RSA key
$ rm server.pass.key
$ openssl req -new -key server.key -out server.csr
...
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
...
A challenge password []:
...
$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

当你访问服务器的时候,由于浏览器默认不信任本身签发的证书,请确保选择 “高级” 和 “继续访问 localhost (不安全)” 或者将 localhost 设置成不安全访问的例外。

点击高级设置

继续访问 localhost (不安全)

初始化、依赖、入口

经过 npm ,初始化项目 package.json ,安装依赖 spdyexpress

npm init
npm i express spdy --save

建立应用的入口文件 index.js ,主要是引用以及实例化

const port = 3000
const spdy = require('spdy')
const express = require('express')
const path = require('path')
const fs = require('fs')

const app = express()

定义 Express.js 的 route

实现 Express.jsroute

app.get('*', (req, res) => {
  res
    .status(200)
    .json({message: 'ok'})
})

设置证书以及启动 Server

经过 fs.readFileSync() 读取证书

const options = {
  key: fs.readFileSync(__dirname + '/server.key'),
  cert: fs.readFileSync(__dirname + '/server.crt')
}

而后,设置证书选项到 Express 对象:

spdy
  .createServer(options, app)
  .listen(port, (error) => {
    if (error) {
      console.error(error)
      return process.exit(1)
    } else {
      console.log('Listening on port: ' + port + '.')
    }
  })

最后,node . 启动服务器

检查结果

经过浏览器的开发者工具查看协议,就如刚刚咱们查看 Yahoo 的 Flickr 协议同样。

开发者工具检查协议

能够看到,使用 Node.js 和 Express.js 配合库 node-spdy 实现 HTTP/2 简单易懂。大多数状况下,对你的业务代码是基本不须要修改的,想必,你的网站也已经使用了 HTTPS/SSL (除非你的服务器只提供静态资源,不然你应该使用安全的 HTTPS/SSL ),即便是不使用 HTTP/2 你也能够替换 HTTP/1.1 而使用 SPDY

固然,在 Node.js 的大环境中,有不少的库,不仅是 node-spdy 提供 HTTP/2 实现,例如:node-http2

结语

HTTP/2 提供了更多更优的好处,并且不用使用复杂的优化技巧。开始享受 HTTP/2 给你带来的这些好处。展望光明的将来!

PS:
本文源代码地址在 http2-express
个人博客

相关文章
相关标签/搜索