永不放弃,永不放弃又有两个原则,第一个原则是永不放弃,第二个原则就是:当你想放弃时回头看第一个原则。

概览

做过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的更多相关文章

  1. 每天学点node系列-stream

    在编写代码时,我们应该有一些方法将程序像连接水管一样连接起来 -- 当我们需要获取一些数据时,可以去通过"拧"其他的部分来达到目的.这也应该是IO应有的方式. -- Doug Mc ...

  2. 每天学点node系列-http

    任何可以使用JavaScript来编写的应用,最终会由JavaScript编写.--Atwood's Law http模块概览 http模块主要用于创建http server服务,并且 支持更多特性 ...

  3. 每天学点node系列-fs文件系统

    好的代码像粥一样,都是用时间熬出来的. 概述 文件 I/O 是由简单封装的标准 POSIX 函数提供的. 通过 require('fs') 使用该模块. 所有文件系统操作都具有同步和异步的形式. 异步 ...

  4. 每天学点node系列-fs文件系统(续)

    理想如果不向现实做一点点屈服,那么理想也将归于尘土. 创建目录 异步创建目录 path<string> | <Buffer> | <URL> options < ...

  5. 我教女朋友学编程html系列(7)—Html无序列表、自定义列表、有序列表及常用例子

    昨天写的那篇文章<我教女朋友学编程Html系列(6)—Html常用表单控件>,基本上有1000人左右看了,那边文章是我站在前人的肩膀上修改来的,添加了截图和说明,合并了例子,使之更容易被初 ...

  6. .Net程序员学用Oracle系列(1):导航目录

    本人从事基于 Oracle 的 .Net 企业级开发近三年,在此之前学习和使用的都是 (MS)SQL Server.未曾系统的了解过 Oracle,所以长时间感到各种不习惯.不方便.怪异和不解,常会遇 ...

  7. .Net程序员学用Oracle系列(2):准备测试环境

    <.Net程序员学用Oracle系列:导航目录> 本文大纲 1.创建说明 1.1.为什么要创建的测试环境? 1.2.了解 Oracle 实例的默认用户 2.创建环境 2.1.创建基本环境 ...

  8. .Net程序员学用Oracle系列(6):表、字段、注释、约束、索引

    <.Net程序员学用Oracle系列:导航目录> 本文大纲 1.表 1.1.创建表 1.2.修改表 & 删除表 2.字段 2.1.添加字段 2.2.修改字段 & 删除字段 ...

  9. .Net程序员学用Oracle系列(7):视图、函数、过程、包

    <.Net程序员学用Oracle系列:导航目录> 本文大纲 1.视图 1.1.创建视图 2.函数 2.1.创建函数 2.2.调用函数 3.过程 3.1.创建过程 3.2.调用过程 4.包 ...

随机推荐

  1. Angular使用echarts

    安装 npm install echarts --save npm install @types/echarts --save 基本使用 定义一个dom <div id="chart& ...

  2. EF学习目录

    EF EF性能优化 EF延迟加载LazyLoading EF相关报错 EF 事务 Entity相互关系 Entity种类(动态代理) DbContext Entity States Code Firs ...

  3. WPF 动态模拟CPU 使用率曲线图

    原文:WPF 动态模拟CPU 使用率曲线图      在工作中经常会遇到需要将一组数据绘制成曲线图的情况,最简单的方法是将数据导入Excel,然后使用绘图功能手动生成曲线图.但是如果基础数据频繁更改, ...

  4. C#如何在VS2015 2017版本中编写WPF UI界面引入第三方SVG图形

    原文:C#如何在VS2015 2017版本中编写WPF UI界面引入第三方SVG图形 在VS2015 2017版本中编写WPF UI界面引入第三方SVG图形     最近在写WPF界面的时候遇到一个情 ...

  5. 生成view的描述字段列表

    ); declare @field_list nvarchar(max); set @table = N'vwMaterial'; set @field_list = N''; SELECT u.na ...

  6. CPU和GPU双低效,摩尔定律之后一万倍 ——写于TPU版AlphaGo重出江湖之际

    本文来自计算机体系结构专家王逵.他认为,“摩尔定律结束之后,性能提升一万倍”不会是科幻,而是发生在我们眼前的事实.   2008年,<三体2:黑暗森林>里写到:   真的很难,你冬眠后不久 ...

  7. Android零基础入门第6节:配置优化SDK Manager,正式约会女神

    原文:Android零基础入门第6节:配置优化SDK Manager,正式约会女神 在前几期中总结分享了Android的前世今生.Android 系统架构和应用组件那些事.带你一起来聊一聊Androi ...

  8. Delphi berlin ShowMessage的改进与使用

    这个版本的delphi对ShowMessage进行了重新实现,更好的适应移动跨平台,即在移动平台下是异步执行的,而在Windows及os X下是同步执行的,如果自己控制是否异步显示对话框,也可以通过T ...

  9. UILabel范例实现代码如下

        #import "TWO_ViewController.h" #define SCREEN_Width [[UIScreen mainScreen] bounds].siz ...

  10. 今天想安装 windowsl ive 提示安装失败 错误码

    Windows Live installation error: OnCatalogResult: 0x80072ee6 看了了这个老兄的回答,试了试,果然OK,谢谢@普洛提亚从这里下载安装包,然后安 ...