首页 >> 精选知识 >

通过实践来聊聊利用Node怎么实现内容压缩

2023-04-27 01:28:17 来源: 用户: 

大家好,综合小编来为大家讲解下通过实践来聊聊利用Node怎么实现内容压缩这个很多人还不知道,现在让我们一起来看看吧!

在查看我的应用日志时,发现进入日志页面后总是需要几秒钟才能加载(界面没有分页),于是打开网络面板查看。

这才发现接口返回的数据没有经过压缩。我以为接口用Nginx做反向代理,Nginx会自动帮我做这一层(这一块后面探讨,理论上可行)。

这里的后端是节点服务。

本文将分享关于HTTP数据压缩的知识以及在节点端的实践。

当具有accept-encoding先验知识的客户端向服务器发送请求时,它会在请求头中添加一个accept-encoding字段,其值表示客户端支持的压缩内容编码格式。

在内容编码服务器压缩返回的内容后,它将内容编码添加到响应头中,以告知浏览器实际内容压缩中使用的编码算法。

Deflate/gzip/brdeflate是一种无损数据压缩算法,同时使用LZ77算法和霍夫曼编码。

Gzip是基于DEFLATE的算法。

Br代表Brotli。这种数据格式旨在进一步提高压缩率。与deflate相比,文本的压缩密度可以提高20%,而压缩和解压缩速度基本相同。

zlib模块Node.js包含一个zlib模块,提供了由Gzip、Deflate/Inflate、Brotli实现的压缩功能。

这里以gzip为例,列举了不同场景下的各种使用模式。Deflate/Inflate的用法和Brotli一样,只是API不同。

基于流的操作

基于缓冲区的操作

介绍几个必备模块。

const zlib=require('zlib')const fs=require('fs')const stream=require('stream')const testFile='tests/origin.log'const targetFile=`${testFile}.gz`const decodeFile=`${testFile}.un.gz`文件的解/压缩解/压缩结果查看,

# 执行du -ah tests# 结果如下108K tests/origin.log.gz2.2M tests/origin.log2.2M tests/origin.log.un.gz4.6M tests基于流(stream)的操作使用createGzip与createUnzip

注:所有zlibAPI,除了那些显式同步的API,都使用Node.js 内部线程池,可以看做是异步的因此下面的示例中的压缩和解压代码应分开执行,

否则会报错方式1:直接利用实例上的pipe方法传递流

//压缩const readStream=fs.createReadStream(testFile)const writeStream=fs.createWriteStream(targetFile)readStream.pipe(zlib.createGzip()).pipe(writeStream)//解压const readStream=fs.createReadStream(targetFile)const writeStream=fs.createWriteStream(decodeFile)readStream.pipe(zlib.createUnzip()).pipe(writeStream)方式2:利用stream上的pipeline,

//压缩const readStream=fs.createReadStream(testFile)const writeStream=fs.createWriteStream(targetFile)stream.pipeline(readStream, zlib.createGzip(), writeStream, err={ if (err) { console.error(err); }})//解压const readStream=fs.createReadStream(targetFile)const writeStream=fs.createWriteStream(decodeFile)stream.pipeline(readStream, zlib.createUnzip(), writeStream, err={ if (err) { console.error(err); }})方式3:Promise化pipeline方法

const { promisify }=require('util')const pipeline=promisify(stream.pipeline)//压缩const readStream=fs.createReadStream(testFile)const writeStream=fs.createWriteStream(targetFile)pipeline(readStream, zlib.createGzip(), writeStream) .catch(err={ console.error(err); })//解压const readStream=fs.createReadStream(targetFile)const writeStream=fs.createWriteStream(decodeFile)pipeline(readStream, zlib.createUnzip(), writeStream) .catch(err={ console.error(err); })基于Buffer的操作利用gzip与unzipAPI,

压缩gzipgzipSync解压unzipunzipSync方式1:将readStream转Buffer,然后进行进一步操作

gzip:异步//压缩const buff=[]readStream.on('data', (chunk)={ buff.push(chunk)})readStream.on('end', ()={ zlib.gzip(Buffer.concat(buff), targetFile, (err, resBuff)={ if(err){ console.error(err); process.exit() } fs.writeFileSync(targetFile,resBuff) })})gzipSync:同步//压缩const buff=[]readStream.on('data', (chunk)={ buff.push(chunk)})readStream.on('end', ()={ fs.writeFileSync(targetFile,zlib.gzipSync(Buffer.concat(buff)))})方式2:直接通过readFileSync读取

//压缩const readBuffer=fs.readFileSync(testFile)const decodeBuffer=zlib.gzipSync(readBuffer)fs.writeFileSync(targetFile,decodeBuffer)//解压const readBuffer=fs.readFileSync(targetFile)const decodeBuffer=zlib.gzipSync(decodeFile)fs.writeFileSync(targetFile,decodeBuffer)文本内容的解/压缩除了对文件压缩,

这里以压缩文本内容为例

//测试数据const testData=fs.readFileSync(testFile, { encoding: 'utf-8' })基于流(stream)操作这块就考虑string= buffer=stream的转换就行

string= buffer

const buffer=Buffer.from(testData)buffer=stream

const transformStream=new stream.PassThrough()transformStream.write(buffer)//orconst transformStream=new stream.Duplex()transformStream.push(Buffer.from(testData))transformStream.push(null)这里以写入到文件示例,

transformStream .pipe(zlib.createGzip()) .pipe(fs.createWriteStream(targetFile))基于Buffer操作同样利用Buffer.from将字符串转buffer

const buffer=Buffer.from(testData)然后直接使用同步API进行转换,这里result就是压缩后的内容

const result=zlib.gzipSync(buffer)可以写入文件,在HTTP Server中也可直接对压缩后的内容进行返回

fs.writeFileSync(targetFile, result)Node Server中的实践这里直接使用Node中http模块创建一个简单的Server 进行演示

在其他的Node Web框架中,处理思路类似,当然一般也有现成的插件,一键接入

本文[高级伪原创标题]到此分享完毕,希望对大家有所帮助。

  免责声明:本文由用户上传,与本网站立场无关。财经信息仅供读者参考,并不构成投资建议。投资者据此操作,风险自担。 如有侵权请联系删除!

 
分享:
最新文章