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

概览

做过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. Qt中嵌入Directx11(有句柄就可以)

    最近要做个游戏场景编辑器,需要directx11配合gui框架使用,所以简单地弄了一个directx11嵌入到Qt窗体中的程序. 1 建立工程 建一个Qt的工程,配置好directx的包含目录和库目录 ...

  2. MFC应用程序配置不正确解决方案(manifest对依赖的强文件名,WinSxs是windows XP以上版本提供的非托管并行缓存)

    [现象] 对这个问题的研究是起源于这么一个现象:当你用VC++2005(或者其它.NET)写程序后,在自己的计算机上能毫无问题地运行,但是当把此exe文件拷贝到别人电脑上时,便不能运行了,大致的错误提 ...

  3. PySide——Python图形化界面入门教程(六)

    PySide——Python图形化界面入门教程(六) ——QListView和QStandardItemModel 翻译自:http://pythoncentral.io/pyside-pyqt-tu ...

  4. TP5.0中使用trace调试

    1.在项目 的配置文件config.php 配置, 2.在程序中使用trace: 3.在浏览器网页上打开 得到如下图所示:点击 “用户变量”,即可查看使用trace输出的变量 或者我们使用 trace ...

  5. 关于SetLocaleInfo()

    原文:关于SetLocaleInfo() 此函数用于设置系统的一些本地信息, 非常有用. 比如日期格式为'yyyy/mm/dd'时, 稍微不注意,有些程序语句会报错. 以下资料网络收集: 1. Set ...

  6. CopyFile函數詳解

    CopyFile函數,文件拷贝函数.其基本結構如下: copyfile( lpcstr lpexistingfilename, // 源文件路径 lpcstr lpnewfilename, //新文件 ...

  7. Tcptrack —— TCP 连接的嗅探器

    分享 <关于我> 分享  [中文纪录片]互联网时代                 http://pan.baidu.com/s/1qWkJfcS 分享 <HTML开发MacOSAp ...

  8. Virtualbox使用点滴(共享USB设备,Linux下我的用户没有加到vboxuser中去)

    由于网银客户端的问题,只能够在windows环境下支付,所以一直保存着一个激活的virtualbox下的windows,用来完成在线支付. 过去这个激活的windows是安装在ubuntu 10.10 ...

  9. 笨重的mfc还在基于系统控件,熟练的mfc工程师还比不过学习Qt一个月的学生开发效率高(比较精彩,韦易笑)

    作者:韦易笑链接:https://www.zhihu.com/question/29636221/answer/45102191来源:知乎著作权归作者所有,转载请联系作者获得授权. 更新:擦,本来只有 ...

  10. Ubuntu 下压缩软件的安装

    在ubuntu下,系统就自带一个压缩包管理软件,但是,它默认是不支持rar和7zip格式的.因此,我们可以给它直接“增强”一下.就成了万能的了.安装方法,终端里面: sudo apt-get inst ...