NodeJS服务器实现gzip压缩的示例代码


Posted in NodeJs onOctober 12, 2018

本文介绍了NodeJS服务器实现gzip压缩,分享给大家,具体如下:

NodeJS服务器实现gzip压缩的示例代码

在浏览器向服务器请求静态资源时,服务器为了减小在网络传输过程中消耗的流量和时间,都是将静态资源经过压缩后返回给服务器的,实现压缩的算法有 deflategzip 等,最常用的是 gzip 压缩。

gzip 简介

在浏览器和服务器之间通过 gzip 压缩流实现传输的过程可以用下图表示。

NodeJS服务器实现gzip压缩的示例代码

当浏览器向服务器请求静态资源,服务器会将静态资源经过处理转换为压缩流,大大减小文件体积,然后将压缩流返回给浏览器,浏览器通过压缩的类型重新将压缩流解析成静态文件。

zlib 模块的使用

1、压缩

在 NodeJS 中通过 zlib 模块帮助我们实现不同类型的压缩,其实压缩的过程就是创建流的过程,创建的压缩流是 Transform 类型(转化流),读取文件的内容经过转化流创建一个新类型的文件。

const zlib = require("zlib");
const fs = require("fs");
const path = require("path");

// 压缩
function gzip(source) {
  // 处理输入和输出的文件路径
  let sourcePath = path.join(__dirname, source);
  let gzipPath = `${sourcePath}.gz`;

  // 创建转化流
  let gzip = zlib.createGzip();

  // 创建可读流
  let rs = fs.createReadStream(sourcePath);

  // 创建可写流
  let ws = fs.createWriteStream(gzipPath);

  // 实现转化
  rs.pipe(gzip).pipe(ws);
}

gzip("index.html");

执行上面代码查看根目路是否出现 index.gz 压缩包。

2、解压

压缩的过程是可逆的,可以压缩就可以解压,无论是在浏览器还是在服务器,我们下面实现解压的方法。

const zlib = require("zlib");
const fs = require("fs");
const path = require("path");

// 解压
function gunzip(source) {
  // 处理输入和输出的文件路径
  let sourcePath = path.join(__dirname, source);
  let filePath = path.join(__dirname, path.basename(source, ".gz"));

  // 创建转化流
  let unzip = zlib.createGunzip();

  // 创建可读流
  let rs = createReadStream(sourcePath);

  // 创建可写流
  let ws = createWriteStream(filePath);

  // 实现转化
  rs.pipe(unzip).pipe(ws);
}

gunzip("index.html.gz");

删除原来 index.html,执行解压代码,查看文件根目录是否生成 index.html

服务器的实现

在浏览器与服务器的交互中,浏览器其实会通过请求头 Accept-Encoding 告诉服务器当前支持解压的压缩格式,值为 gzip, deflate, br,多个压缩格式用 , 隔开,服务器在接收到浏览器请求后,会按照请求头的格式压缩资源,将压缩后的资源返回,并通过响应头 Content-Encoding 告诉浏览器当前服务器压缩的格式。

// 引入依赖
const http = require("http");
const url = require("url");
const path = require("path");
const fs = require("fs");
const zlib = require("zlib");

// 创建服务器
const server = http.createServer((req, res) => {
  // 处理 pathname,"/" 时默认读取 "/index.html"
  let { pathname } = url.parse(req.url, true);
  pathname = pathname !== "/" ? pathname : "/index.html";

  // 获取读取文件的绝对路径
  let p = path.join(__dirname, pathname);

  // 查看路径是否合法
  fs.access(p, err => {
    // 路径不合法则直接中断连接
    if (err) return res.end("Not Found");

    // 获取浏览器支持的压缩格式
    let encoding = req.headers["accept-encoding"];

    // 创建可读流
    let rs = fs.createReadStream(p);

    // 支持 gzip 使用 gzip 压缩,支持 deflate 使用 deflate 压缩
    if (encoding && encoding.match(/\bgzip\b/)) {
      let compress = zlib.createGzip();
      let compressType = "gzip";
    } else if (encoding && encoding.match(/\bdeflate\b/)) {
      let compress = zlib.createDeflate();
      let compressType = "deflate";
    } else {
      // 否则直接返回可读流
      return rs.pipe(res);
    }

    // 将压缩流返回并设置响应头
    res.setHeader("Content-Encoding", compressType);
    rs.pipe(compress).pipe(res);
  });
});

server.listen(3000, () => {
  console.log("server start 3000");
});

在上面服务器中如果不通过响应头通知浏览器当前资源的压缩格式,浏览器会不知道该如何解压,默认会当成文件下载,如 Chrome,所以在返回压缩流时必须通过 Content-Encoding 响应头通知浏览器当前的压缩格式。

测试服务器压缩

我们在文件根目录创建一个 index.html 文件,代码如下。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>gzip</title>
</head>
<body>
  <div>Hello GZIP!</div>
</body>
</html>

启动服务器 server.js,然后通过浏览器访问 localhost:3000,查看页面能否正确返回,并查看开发者工具 Network 中的响应头 Content-Encoding 的值是否正确。

总结

服务器压缩其实是客户端与服务器在网络传输时的一种优化手段,可以大大减小流量的消耗和响应时间,而 gzip 只是目前最常用的一种压缩格式,即压缩算法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
nodejs中转换URL字符串与查询字符串详解
Nov 26 NodeJs
Nodejs实现多人同时在线移动鼠标的小游戏分享
Dec 06 NodeJs
轻松创建nodejs服务器(4):路由
Dec 18 NodeJs
轻松创建nodejs服务器(9):实现非阻塞操作
Dec 18 NodeJs
Windows系统中安装nodejs图文教程
Feb 28 NodeJs
用nodeJS搭建本地文件服务器的几种方法小结
Mar 16 NodeJs
nodejs实现邮件发送服务实例分享
Mar 29 NodeJs
nodejs个人博客开发第七步 后台登陆
Apr 12 NodeJs
NodeJS链接MySql数据库的操作方法
Jun 27 NodeJs
详解nodejs通过响应回写的方式渲染页面资源
Apr 07 NodeJs
nodejs 十六进制字符串型数据与btye型数据相互转换
Jul 30 NodeJs
nodejs读取图片返回给浏览器显示
Jul 25 NodeJs
nodejs aes 加解密实例
Oct 10 #NodeJs
nodejs读取本地中文json文件出现乱码解决方法
Oct 10 #NodeJs
nodejs require js文件入口,在package.json中指定默认入口main方法
Oct 10 #NodeJs
nodejs更新package.json中的dependencies依赖到最新版本的方法
Oct 10 #NodeJs
nodejs中用npm初始化来创建package.json的实例讲解
Oct 10 #NodeJs
nodejs初始化init的示例代码
Oct 10 #NodeJs
webpack打包nodejs项目的方法
Sep 26 #NodeJs
You might like
黑夜路人出的几道php笔试题
2009/08/04 PHP
mysql From_unixtime及UNIX_TIMESTAMP及DATE_FORMAT日期函数
2010/03/21 PHP
php中unserialize返回false的解决方法
2014/09/22 PHP
PHP中使用array函数新建一个数组
2015/11/19 PHP
php根据年月获取当月天数及日期数组的方法
2016/11/30 PHP
php递归函数怎么用才有效
2018/02/24 PHP
laravel-admin 在列表页添加自定义按钮的例子
2019/09/30 PHP
基于Jquery的回车成tab焦点切换效果代码(Enter To Tab )
2010/11/14 Javascript
jquery 使用点滴函数代码
2011/05/20 Javascript
jquery ajax的success回调函数中实现按钮置灰倒计时
2013/11/19 Javascript
JS小游戏之仙剑翻牌源码详解
2014/09/25 Javascript
JS实现网页标题栏显示当前时间和日期的完整代码
2015/11/02 Javascript
讲解JavaScript的Backbone.js框架的MVC结构设计理念
2016/02/14 Javascript
bootstarp modal框居中显示的实现代码
2017/02/18 Javascript
jQuery实现打开网页自动弹出遮罩层或点击弹出遮罩层功能示例
2017/10/19 jQuery
vue获取dom元素注意事项
2017/12/28 Javascript
vue实现表单录入小案例
2019/09/27 Javascript
简单使用webpack打包文件的实现
2019/10/29 Javascript
解读Django框架中的低层次缓存API
2015/07/24 Python
Python实现简单的获取图片爬虫功能示例
2017/07/12 Python
numpy中索引和切片详解
2017/12/15 Python
在win10和linux上分别安装Python虚拟环境的方法步骤
2019/05/09 Python
使用Tensorflow将自己的数据分割成batch训练实例
2020/01/20 Python
python匿名函数lambda原理及实例解析
2020/02/07 Python
浅谈CSS3动画的回调处理
2016/07/21 HTML / CSS
日本非常有名的内衣丝袜品牌:GUNZE
2017/01/06 全球购物
LN-CC美国:伦敦时尚生活的缩影
2019/02/19 全球购物
Fossil加拿大官网:化石手表、手袋、首饰及配饰
2019/04/23 全球购物
德国家具折扣店:POCO
2020/02/28 全球购物
中学生国旗下讲话稿
2014/04/26 职场文书
素质教育学习心得体会
2016/01/19 职场文书
2016年村干部公开承诺书(公开承诺事项)
2016/03/25 职场文书
2016年幼儿园教研活动总结
2016/04/05 职场文书
MySQL的索引你了解吗
2022/03/13 MySQL
vue2的 router在使用过程中遇到的一些问题
2022/04/13 Vue.js
win10搭建配置ftp服务器的方法
2022/08/05 Servers