使用 Node.js 和 Express.js 搭建简易 HTTP/2 服务器

自从 1975 年左右使用 TCP/IP 协议的现代互联网诞生至今已经过了惊人的41年了。在它生涯的大部分时间里,我们使用 HTTP 以及它的继任者 HTTP/1.1 (1.1 版本) 在客户端和服务器之间进行通讯。它很好的支撑起了这个网络世界,但是开发者们构建网站的方式发生了巨大的变化。现在有无数的外部资源、图片、CSS 文件和 JavaScript 文件。这些资源的数量只增不减。

HTTP2 是这 15 年以来对这个好用但是陈旧的 HTTP 协议的第一次重大升级 (第一版的 HTTP 协议大约是 1991 年发布的)!它是为现代网站而优化的。它拥有更好的性能,而不需要一些复杂的 hack 手段,类似域名分散 (使用多个域名) 或者文件合并 (使用一个大文件代替许多小文件)。

H2 是 web 的新标准,它的前身是 Google 的 SPDY 协议。它已经被很多流行的网站使用,并且得到了大多数主流浏览器的支持。举个例子,访问 Yahoo 的 Flickr,可以看到它已经在使用 h2 (HTTP2) 协议 (截止 2016 年 1 月)。

Yahoo 的 Flickr 已经用上了 h2 (HTTP2) 协议

HTTP/2 在语义上和 HTTP/1.1 没有任何差别,这意味着你可以在协议报文中使用相同的 XML 类语言,以及相同的报头字段、状态码、cookie、请求方式、URL地址等等。开发者们熟悉的那些东西在 H2 中还是一样的。H2 的优点包括:

  1. 多路复用:允许浏览器在一个 TCP 连接中包含多个请求,从而使得浏览器可以并行请求所有资源。
  2. 服务器推送:服务器可以在浏览器需要之前主动推送 web 资源 (CSS,JS, 图片),这样可以减少请求数,提高页面加载速度。
  3. 串流优先:允许浏览器指定资源的优先级。比如,浏览器可以在所有样式和 JavaScript 之前优先请求 HTML 来渲染。
  4. 头压缩:所有的 HTTP/1.1 请求中必须要包含一些经常冗余的头信息,不过 H2 强制所有的 HTTP 报头以一种压缩的格式进行发送。
  5. 事实强制加密:尽管加密不是必须的,大多数主流浏览器只支持使用 TLS (HTTPS) 的 H2。

尽管对 H2 还有一些批评,不过很明显目前看来这都是一种进步 (除非我们能找到更好的)。因此,我们来看看作为一个 web 开发者你需要知道些什么。首先,你以前知道的大部分优化技巧都已经不再需要了,这其中的一些甚至会影响网站性能。没错,我说的就是文件合并。不要再做这些 (图片 sprites,合并 CSS 和 JS) 了,因为大文件中的一点点小改动就会导致缓存失效。保持许多的小文件是更好的姿势。正因于此,我希望大家今后不再使用类似 Grunt,Gulp 和 Webpack 这类构建工具。它们会带来额外的复杂性,陡峭的学习曲线和对 web 项目的依赖性。

[广告时间]: 如果你喜欢这篇文章并且想要更多的了解 大前端的一切,请扫描下面的二维码报名。

现在就开始掌握大前端全站开发的必要技术。参加京程一灯课程提升你的职业技能。熟悉 JavaScript + Node.js 的全栈开发。通过 这里 的学习获取新技能和对未来的自信。[广告结束]

优秀的开发者们在 HTTP/1.1 世界会做的另一件事,同时在 H2 里会影响性能的,就是域名分散 (一种跨过浏览器的 TCP 连接数限制的技巧)。OK,这个可能不会影响所有的情况,不过现在有了多路复用,这个已经没有任何必要了。不要在 HTTP2 里做域名分散还因为每个域名会带来额外的开销。如果你一定要这么做,请搞定让所有的域名使用同一个 IP,并且确保你有一个有效的子域名通配符证书或者多域名证书。

有关 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
写入 RSA 密钥
$ rm server.pass.key
$ openssl req -new -key server.key -out server.csr
...
国家名 (2 个字母的代码) [AU]:US
州或省名 (全名) [Some-State]:California
...
一个复杂的密码 []:
...
$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

当你访问自己的服务器,记得选择 “ADVANCED” 和 “Proceed to localhost (unsafe)” 或者把 localhost 添加到例外中。这么做的原因是浏览器默认不信任自签名的证书。

选择 ADVANCED

但是这是你自己的证书,因此这么处理是 ok 的。

选择 Proceed to localhost (unsafe)

然后我们需要初始化 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 路由:

再次广告:如果你喜欢这篇文章并对可以提高团队效率的 JavaScript、Node.js 和 React.js 培训感兴趣,请扫描下面的二维码报名。

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

然后,我们需要加载密钥和证书文件。这可能是我们为数不多能用到 fs.readFileSync() 的地方之一:

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

最后,我们在 Express 实例创建的服务器中加载 SSL 选项:

spdy
  .createServer(options, app)

往期精选文章

使用虚拟dom和JavaScript构建完全响应式的UI框架

扩展 Vue 组件

使用Three.js制作酷炫无比的无穷隧道特效

一个治愈JavaScript疲劳的学习计划

全栈工程师技能大全

WEB前端性能优化常见方法

一小时内搭建一个全栈Web应用框架

干货:CSS 专业技巧

四步实现React页面过渡动画效果

让你分分钟理解 JavaScript 闭包



小手一抖,资料全有。长按二维码关注京程一灯,阅读更多技术文章和业界动态。

原文发布于微信公众号 - 京程一灯(jingchengyideng)

原文发表时间:2017-09-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券