每天学点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.包 ...
 
随机推荐
- QT实现鼠标钩子(使用SetWindowsHookEx安装mouseProc函数)
			
HHOOK mouseHook=NULL; LRESULT CALLBACK mouseProc(int nCode,WPARAM wParam,LPARAM lParam ) { if(nCode ...
 - 扩展ASCII码,不同的国家有不同的字符集。Unicode转换为utf8的规则,utf8没有大小端的问题。超过0xFFFF的Unicode字符WINAPI也无能为力(附各种字符编码表及转换表)good
			
一.概念 1,ASCII ASCII(American Standard Code for Information Interchange),中文名称为美国信息交换标准代码.是 ...
 - ARM中 __IO的作用解析
			
__IO在头文件中预定义 #define __IO volatile volatile 影响编译器编译的结果, 指出:volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要 ...
 - 探究操作系统的内存分配(malloc)对齐策略
			
问题: 我们在写程序的时候经常发现程序使用的内存往往比我们申请的多,为了优化程序的内存占用,搅尽脑汁想要优化内存占用,可是发现自己的代码也无从优化了,怎么办?现在我们把我们的焦点放到malloc上,毕 ...
 - 图像滤镜艺术---Photoshop实现Instagram   Amaro滤镜特效
			
原文:图像滤镜艺术---Photoshop实现Instagram Amaro滤镜特效 本文是我收集的一些使用Photoshop来实现Instagram滤镜的一些内容,在这里跟大家分享一下,这些效果是完 ...
 - 【Linux】Linux中常用操作命令(转)
			
Linux简介及Ubuntu安装 Linux,免费开源,多用户多任务系统.基于Linux有多个版本的衍生.RedHat.Ubuntu.Debian 安装VMware或VirtualBox虚拟机.具体安 ...
 - 指定Qt程序运行的style,比如fusion(以前没见过QStyleFactory)
			
转载请注明文章:指定Qt程序运行的style,比如fusion 出处:多客博图 代码很简单,如下: #include <QtWidgets/QApplication> #include ...
 - Cindy components(配色很不错)
			
https://sourceforge.net/projects/tcycomponents/
 - Delphi 编写ActiveX控件(OCX控件)的知识和样例(有详细步骤)
			
一.ActiveX应用情况简介: ActiveX控件也就是一般所说的OCX控件,它是 ActiveX技术的一部分.ActiveX是微软公司推出的基于组件对象模型COM的技术,包括对Windows 32 ...
 - spring3升级到spring4通用异常处理返回jsonp多了/**/的解决办法
			
问题描述 在spring3中定义了通用的异常处理,具体代码如下: public class CommonExceptionHandler implements HandlerExceptionReso ...