每天学点node系列-zlib
永不放弃,永不放弃又有两个原则,第一个原则是永不放弃,第二个原则就是:当你想放弃时回头看第一个原则。
概览
做过web性能优化的同学,对性能优化大杀器gzip应该不陌生。浏览器向服务器发起资源请求,比如下载一个js文件,服务器先对资源进行压缩,再返回给浏览器,以此节省流量,加快访问速度。
浏览器通过HTTP请求头部里加上Accept-Encoding,告诉服务器,“你可以用gzip,或者defalte算法压缩资源”。

那么,在nodejs里,是如何对资源进行压缩的呢?答案就是Zlib模块。
Zlib
zlib模块提供 Gzip 和 Deflate/Inflate 来实现压缩功能.
压缩
const zlib = require('zlib')
const fs = require('fs')
const gzip = zlib.createGzip()
const inp = fs.createReadStream('1.txt')
const out = fs.createWriteStream('1.txt.gz')
inp.pipe(gzip).pipe(out)
解压
const zlib = require('zlib')
var fs = require('fs')
var gunzip = zlib.createGunzip()
var inFile = fs.createReadStream('./1.txt.gz')
var outFile = fs.createWriteStream('./2.txt')
inFile.pipe(gunzip).pipe(outFile)
解/压缩HTTP请求和响应
zlib 可以用来实现对 HTTP 中定义的 gzip 和 deflate 内容编码机制的支持。
HTTP 的 Accept-Encoding 头字段用来标记客户端接受的压缩编码。
压缩服务端响应
// 服务端示例
// 对每一个请求运行 gzip 操作的成本是十分高昂的.
// 缓存压缩缓冲区是更加高效的方式.
const zlib = require('zlib')
const http = require('http')
const fs = require('fs')
http.createServer((req, res) => {
const raw = fs.createReadStream('index.html')
let acceptEncoding = req.headers['accept-encoding']
if (!acceptEncoding) {
acceptEncoding = ''
}
if (/\bdeflate\b/.test(acceptEncoding)) {
res.writeHead(200, { 'Content-Encoding': 'deflate' })
raw.pipe(zlib.createDeflate()).pipe(res)
} else if (/\bgzip\b/.test(acceptEncoding)) {
res.writeHead(200, { 'Content-Encoding': 'gzip' })
raw.pipe(zlib.createGzip()).pipe(res)
} else {
res.writeHead(200, {})
raw.pipe(res)
}
}).listen(3000)
解压客户端请求
// 客户端请求示例
const zlib = require('zlib')
const http = require('http')
const fs = require('fs')
const request = http.get({
host: 'localhost.com',
path: '/',
port: 3000,
headers: { 'Accept-Encoding': 'gzip,deflate' } })
request.on('response', (response) => {
const output = fs.createWriteStream('index.html')
switch (response.headers['content-encoding']) {
// 或者, 只是使用 zlib.createUnzip() 方法去处理这两种情况
case 'gzip':
response.pipe(zlib.createGunzip()).pipe(output)
break
case 'deflate':
response.pipe(zlib.createInflate()).pipe(output)
break
default:
response.pipe(output)
break
}
})
默认情况下, 当解压不完整的数据时 zlib 方法会抛出一个错误. 然而, 如果它已经知道数据是不完整的, 或者仅仅是为了检查已压缩文件的开头, 可以通过改变用来解压最后一个的输入数据块的刷新方法来避免默认的错误处理.
const zlib = require('zlib')
const buffer = Buffer.from('eJzT0yMA', 'base64');
zlib.unzip(buffer, { finishFlush: zlib.constants.Z_SYNC_FLUSH }, (err, buffer) => {
if (!err) {
console.log(buffer.toString());
} else {
// 错误处理
}
})
相关链接
http://nodejs.cn/api/zlib.html
每天学点node系列-zlib的更多相关文章
- 每天学点node系列-stream
在编写代码时,我们应该有一些方法将程序像连接水管一样连接起来 -- 当我们需要获取一些数据时,可以去通过"拧"其他的部分来达到目的.这也应该是IO应有的方式. -- Doug Mc ...
- 每天学点node系列-http
任何可以使用JavaScript来编写的应用,最终会由JavaScript编写.--Atwood's Law http模块概览 http模块主要用于创建http server服务,并且 支持更多特性 ...
- 每天学点node系列-fs文件系统
好的代码像粥一样,都是用时间熬出来的. 概述 文件 I/O 是由简单封装的标准 POSIX 函数提供的. 通过 require('fs') 使用该模块. 所有文件系统操作都具有同步和异步的形式. 异步 ...
- 每天学点node系列-fs文件系统(续)
理想如果不向现实做一点点屈服,那么理想也将归于尘土. 创建目录 异步创建目录 path<string> | <Buffer> | <URL> options < ...
- 我教女朋友学编程html系列(7)—Html无序列表、自定义列表、有序列表及常用例子
昨天写的那篇文章<我教女朋友学编程Html系列(6)—Html常用表单控件>,基本上有1000人左右看了,那边文章是我站在前人的肩膀上修改来的,添加了截图和说明,合并了例子,使之更容易被初 ...
- .Net程序员学用Oracle系列(1):导航目录
本人从事基于 Oracle 的 .Net 企业级开发近三年,在此之前学习和使用的都是 (MS)SQL Server.未曾系统的了解过 Oracle,所以长时间感到各种不习惯.不方便.怪异和不解,常会遇 ...
- .Net程序员学用Oracle系列(2):准备测试环境
<.Net程序员学用Oracle系列:导航目录> 本文大纲 1.创建说明 1.1.为什么要创建的测试环境? 1.2.了解 Oracle 实例的默认用户 2.创建环境 2.1.创建基本环境 ...
- .Net程序员学用Oracle系列(6):表、字段、注释、约束、索引
<.Net程序员学用Oracle系列:导航目录> 本文大纲 1.表 1.1.创建表 1.2.修改表 & 删除表 2.字段 2.1.添加字段 2.2.修改字段 & 删除字段 ...
- .Net程序员学用Oracle系列(7):视图、函数、过程、包
<.Net程序员学用Oracle系列:导航目录> 本文大纲 1.视图 1.1.创建视图 2.函数 2.1.创建函数 2.2.调用函数 3.过程 3.1.创建过程 3.2.调用过程 4.包 ...
随机推荐
- 2017 JavaScript 开发者的学习图谱
码云项目推荐 前端框架类 1.项目名称: 基于 Vue.js 的 UI 组件库 iView 项目简介:iView 是一套基于 Vue.js 的 UI 组件库,主要服务于 PC 界面的中后台产品. 特性 ...
- jquery 选择标题标签
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- Win10《芒果TV》更新v3.5.0夏至版:会员尊享蓝光画质,关联本地视频播放
在Win10秋季创意者更新前夕,Win10版<芒果TV>全平台同步更新夏至版v3.5.0,新增会员蓝光画质,关联本地视频播放,进一步提升使用体验. Win10版<芒果TV>V3 ...
- 《KVM虚拟化技术实战和原理解析》读书笔记(十几篇)
第一章和第二章 第一章 虚拟化和云计算 Saas(软件即服务):将已经部署好的软件作为一种服务来提供,比如:Google Docs, Google Apps Paas(平台即服务):将开发环境作为一种 ...
- MongoDB对文档的操作
插入文档 db.COLLECTION_NAME.insert({doc1},{doc2},...) e.g.:db.collection.insert({name:'123',age:12},{nam ...
- Wolf RPG Editor游戏解包
前言 使用arc_conv_r53进行解包 使用touhouSE进行解包 使用DXEXTRACT进行解包 前言 Wolf RPG Editor由于其需要翻来覆去的转码,脚本名称等问题算是解包跟汉化中比 ...
- c# log4net 配置使用
新增配置文件log4net.config,内容如下 <?xml version="1.0" encoding="utf-8" ?> <conf ...
- 剖析Qt的事件机制原理(源代码级别)
在用Qt写Gui程序的时候,在main函数里面最后依据都是app.exec();很多书上对这句的解释是,使Qt程序进入消息循环.下面我们就到exec()函数内部,来看一下他的实现原理.Let's go ...
- 【canvas】基础练习三 图片
[canvas]Demo1 drawImage drawImage(img,x,y); <!DOCTYPE html> <html lang="en"> & ...
- DataVeryLite和Nhibernate性能对比
电脑型号:acer 4752g 电脑配置: 代码分享: class Program { static void Main(string[] args) { Debug.Listeners.Add(ne ...