


Parlons de la façon d'utiliser Node pour réaliser la compression de contenu grâce à la pratique
Comment réaliser une compression de contenu à l'aide de Nodejs ? L'article suivant parlera de la méthode d'implémentation de la compression de contenu (gzip/br/deflate) côté Node par la pratique. J'espère que cela vous sera utile !
Lorsque je vérifiais mon journal application, j'ai constaté que le chargement prenait toujours quelques secondes après être entré dans la page du journal (l'interface n'était pas paginée), j'ai donc ouvert le panneau réseau pour vérifier
ce n'est qu'à ce moment-là que j'ai découvert que les données renvoyées par l'interface n'étaient pas compressées. Je pensais que l'interface utilisait le proxy inverse Nginx, et Nginx m'aiderait automatiquement à faire cette couche (j'explorerai cela plus tard, c'est le cas). théoriquement réalisable)
Le backend ici est Node Service
Cet article partagera les connaissances sur la Compression de données HTTP
et la pratique du Côté nœud
HTTP数据压缩
相关知识以及在Node侧的实践
前置知识
下面的客户端均指浏览器
accept-encoding
客户端在向服务端发起请求时,会在请求头(request header)中添加accept-encoding
字段,其值标明客户端支持的压缩内容编码
格式
content-encoding
服务端在对返回内容执行压缩后,通过在响应头(response header)中添加content-encoding
,来告诉浏览器内容实际压缩使用的编码算法
deflate/gzip/br
deflate
是同时使用了LZ77
算法与哈夫曼编码(Huffman Coding)
的一个无损数据压缩算法。
gzip
是基于 DEFLATE
的算法
br
指代Brotli
,该数据格式旨在进一步提高压缩比,对文本的压缩相对deflate
能增加20%
的压缩密度,而其压缩与解压缩速度则大致不变
zlib模块
Node.js包含一个zlib 模块
,提供了使用 Gzip
、Deflate/Inflate
、以及 Brotli
实现的压缩功能
这里以gzip
为例分场景列举多种使用方式,Deflate/Inflate
与Brotli
使用方式一样,只是API不一样
基于stream
的操作
基于buffer
的操作
引入几个所需的模块
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
指令直接统计解压缩前后结果
# 执行 du -ah tests # 结果如下 108K tests/origin.log.gz 2.2M tests/origin.log 2.2M tests/origin.log.un.gz 4.6M tests
基于流(stream)
的操作
使用createGzip
与createUnzip
- 注:所有
zlib
API,除了那些显式同步的 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
与 unzip
API,这两个方法包含同步
与异步
类型
- 压缩
gzip
gzipSync
- 解压
unzip
unzipSync
方式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
Connaissances préalablesLes clients suivants font tous référence aux navigateurs
accepter-encodage
Les clients suivants font tous référence aux navigateurs
accept-encoding
dans l'(en-tête de la requête), dont la valeur indique le format de codage de contenu compressé pris en charge
par le client. 🎜contenu -encodage
🎜l'algorithme d'encodage utilisé pour la compression réelle< en ajoutant <code>content -encoding
à l'en-tête de réponse /code>🎜deflate/gzip/br
🎜deflate
utilise à la fois le LZ77
et Huffman Coding
sont un algorithme de compression de données sans perte. 🎜🎜gzip
est un algorithme basé sur DEFLATE
🎜🎜br
fait référence à Brotli
, qui est un format de données conçu pour améliorer encore le taux de compression, la compression du texte peut augmenter la densité de compression de 20 %
par rapport au dégonfler
, tandis que la vitesse de compression et de décompression reste à peu près la même🎜module zlib 🎜🎜Node.js contient un module zlib
, qui permet l'utilisation de Gzip
, Deflate/Inflate
, et Fonction de compression implémentée par Brotli
🎜🎜Ici, nous prenons gzip
comme exemple pour lister diverses méthodes d'utilisation selon les scénarios, Dégonfler/Dégonfler
et Brotli</code >L'utilisation est la même, mais l'API est différente🎜🎜<strong>Fonctionnement basé sur le <code>stream
🎜🎜
🎜🎜Opérations basées sur le buffer</ code></strong>🎜🎜<img src="https://img.php.cn/upload/image/734/331/536/164674055924407Parlons de la façon dutiliser Node pour réaliser la compression de contenu grâce à la pratique" title="164674055924407Parlons de la façon dutiliser Node pour réaliser la compression de contenu grâce à la pratique" alt="Parlons de la façon dutiliser Node pour réaliser la compression de contenu grâce à la pratique "/>🎜🎜Introduire plusieurs modules requis 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>// 压缩
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)</pre><div class="contentsignin">Copier après la connexion</div></div><h2 data-id="heading-6">Décompression/compression de fichiers🎜🎜Afficher les résultats de décompression/compression, utilisez ici la commande <code>du
pour compter directement les résultats avant et après décompression🎜// 测试数据
const testData = fs.readFileSync(testFile, { encoding: 'utf-8' })
Copier après la connexionCopier après la connexionOpérations basées sur stream
🎜Utilisez createGzip
et createUnzip
🎜- Remarque : Toutes les API
zlib
, à l'exception de celles qui sont explicitement synchrones, utilisent le pool de threads interne de Node.js et peuvent être considérées comme asynchrones - Donc ce qui suit Le code de compression et de décompression dans l'exemple doit être exécuté séparément, sinon une erreur sera signalée
🎜Méthode 1 : Utilisez directement le pipe< /code> sur l'instance pour transmettre le flux🎜 <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>const buffer = Buffer.from(testData)</pre><div class="contentsignin">Copier après la connexion</div></div><div class="contentsignin">Copier après la connexion</div></div><div class="contentsignin">Copier après la connexion</div></div><div class="contentsignin">Copier après la connexion</div></div>🎜<strong>Méthode 2 :</strong> En utilisant le <code>pipeline
sur stream
, vous pouvez effectuer d'autres traitements séparément pendant le rollback🎜const transformStream = new stream.PassThrough()
transformStream.write(buffer)
// or
const transformStream = new stream.Duplex()
transformStream.push(Buffer.from(testData))
transformStream.push(null)
Copier après la connexionCopier après la connexion🎜Méthode 3 : Méthode pipeline
promise🎜transformStream
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream(targetFile))
Copier après la connexionCopier après la connexion Opération basée sur Buffer</code ></h3>🎜Utilisez les API <code> gzip
et unzip
, ces deux méthodes incluent les types synchrone
et asynchrone
🎜< ul>
Compression gzip
gzipSync
Décompresserdécompresser
décompresserSync
🎜 Méthode 1 : readStream
vers Buffer
, puis effectuera d'autres opérations🎜- gzip : asynchrone
const buffer = Buffer.from(testData)
Copier après la connexionCopier après la connexionCopier après la connexionCopier après la connexion - gzipSync : synchronisé< /li>
const result = zlib.gzipSync(buffer)
Copier après la connexionCopier après la connexion🎜Méthode 2 : Lire 🎜fs.writeFileSync(targetFile, result)
Copier après la connexionCopier après la connexion🎜décompression/compression du contenu texte directement via readFileSync
🎜 🎜En plus de la compression des fichiers, parfois peut-être Pour décompresser directement le contenu transféré🎜这里以压缩文本内容为例
// 测试数据
const testData = fs.readFileSync(testFile, { encoding: 'utf-8' })
Copier après la connexionCopier après la connexion基于流(stream)
操作
这块就考虑 string
=> buffer
=> stream
的转换就行
string
=> buffer
const buffer = Buffer.from(testData)
Copier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionbuffer
=> stream
const transformStream = new stream.PassThrough()
transformStream.write(buffer)
// or
const transformStream = new stream.Duplex()
transformStream.push(Buffer.from(testData))
transformStream.push(null)
Copier après la connexionCopier après la connexion这里以写入到文件示例,当然也可以写到其它的流里,如HTTP的Response
(后面会单独介绍)
transformStream
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream(targetFile))
Copier après la connexionCopier après la connexion基于Buffer
操作
同样利用Buffer.from
将字符串转buffer
const buffer = Buffer.from(testData)
Copier après la connexionCopier après la connexionCopier après la connexionCopier après la connexion然后直接使用同步API进行转换,这里result就是压缩后的内容
const result = zlib.gzipSync(buffer)
Copier après la connexionCopier après la connexion可以写入文件,在HTTP Server
中也可直接对压缩后的内容进行返回
fs.writeFileSync(targetFile, result)
Copier après la connexionCopier après la connexionNode Server中的实践
这里直接使用Node中 http
模块创建一个简单的 Server 进行演示
在其他的 Node Web
框架中,处理思路类似,当然一般也有现成的插件,一键接入

const http = require('http')
const { PassThrough, pipeline } = require('stream')
const zlib = require('zlib')
// 测试数据
const testTxt = '测试数据123'.repeat(1000)
const app = http.createServer((req, res) => {
const { url } = req
// 读取支持的压缩算法
const acceptEncoding = req.headers['accept-encoding'].match(/(br|deflate|gzip)/g)
// 默认响应的数据类型
res.setHeader('Content-Type', 'application/json; charset=utf-8')
// 几个示例的路由
const routes = [
['/gzip', () => {
if (acceptEncoding.includes('gzip')) {
res.setHeader('content-encoding', 'gzip')
// 使用同步API直接压缩文本内容
res.end(zlib.gzipSync(Buffer.from(testTxt)))
return
}
res.end(testTxt)
}],
['/deflate', () => {
if (acceptEncoding.includes('deflate')) {
res.setHeader('content-encoding', 'deflate')
// 基于流的单次操作
const originStream = new PassThrough()
originStream.write(Buffer.from(testTxt))
originStream.pipe(zlib.createDeflate()).pipe(res)
originStream.end()
return
}
res.end(testTxt)
}],
['/br', () => {
if (acceptEncoding.includes('br')) {
res.setHeader('content-encoding', 'br')
res.setHeader('Content-Type', 'text/html; charset=utf-8')
// 基于流的多次写操作
const originStream = new PassThrough()
pipeline(originStream, zlib.createBrotliCompress(), res, (err) => {
if (err) {
console.error(err);
}
})
originStream.write(Buffer.from('<h1 id="BrotliCompress">BrotliCompress</h1>'))
originStream.write(Buffer.from('<h2 id="测试数据">测试数据</h2>'))
originStream.write(Buffer.from(testTxt))
originStream.end()
return
}
res.end(testTxt)
}]
]
const route = routes.find(v => url.startsWith(v[0]))
if (route) {
route[1]()
return
}
// 兜底
res.setHeader('Content-Type', 'text/html; charset=utf-8')
res.end(`<h1 id="nbsp-url">404: ${url}</h1>
<h2 id="已注册路由">已注册路由</h2>
<ul>
${routes.map(r => `<li><a href="${r[0]}">${r[0]}</a></li>`).join('')}
</ul>
`)
res.end()
})
app.listen(3000)
Copier après la connexion更多node相关知识,请访问:nodejs 教程!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!
// 测试数据 const testData = fs.readFileSync(testFile, { encoding: 'utf-8' })
stream
zlib
, à l'exception de celles qui sont explicitement synchrones, utilisent le pool de threads interne de Node.js et peuvent être considérées comme asynchronesconst transformStream = new stream.PassThrough() transformStream.write(buffer) // or const transformStream = new stream.Duplex() transformStream.push(Buffer.from(testData)) transformStream.push(null)
transformStream .pipe(zlib.createGzip()) .pipe(fs.createWriteStream(targetFile))
Buffer</code ></h3>🎜Utilisez les API <code> gzip
et unzip
, ces deux méthodes incluent les types synchrone
et asynchrone
🎜< ul>gzip
gzipSync
décompresser
décompresserSync
const buffer = Buffer.from(testData)
const result = zlib.gzipSync(buffer)
fs.writeFileSync(targetFile, result)
// 测试数据 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) // or const transformStream = new stream.Duplex() transformStream.push(Buffer.from(testData)) transformStream.push(null)
HTTP的Response
(后面会单独介绍)transformStream .pipe(zlib.createGzip()) .pipe(fs.createWriteStream(targetFile))
Buffer
操作Buffer.from
将字符串转buffer
const buffer = Buffer.from(testData)
const result = zlib.gzipSync(buffer)
HTTP Server
中也可直接对压缩后的内容进行返回fs.writeFileSync(targetFile, result)
http
模块创建一个简单的 Server 进行演示Node Web
框架中,处理思路类似,当然一般也有现成的插件,一键接入const http = require('http') const { PassThrough, pipeline } = require('stream') const zlib = require('zlib') // 测试数据 const testTxt = '测试数据123'.repeat(1000) const app = http.createServer((req, res) => { const { url } = req // 读取支持的压缩算法 const acceptEncoding = req.headers['accept-encoding'].match(/(br|deflate|gzip)/g) // 默认响应的数据类型 res.setHeader('Content-Type', 'application/json; charset=utf-8') // 几个示例的路由 const routes = [ ['/gzip', () => { if (acceptEncoding.includes('gzip')) { res.setHeader('content-encoding', 'gzip') // 使用同步API直接压缩文本内容 res.end(zlib.gzipSync(Buffer.from(testTxt))) return } res.end(testTxt) }], ['/deflate', () => { if (acceptEncoding.includes('deflate')) { res.setHeader('content-encoding', 'deflate') // 基于流的单次操作 const originStream = new PassThrough() originStream.write(Buffer.from(testTxt)) originStream.pipe(zlib.createDeflate()).pipe(res) originStream.end() return } res.end(testTxt) }], ['/br', () => { if (acceptEncoding.includes('br')) { res.setHeader('content-encoding', 'br') res.setHeader('Content-Type', 'text/html; charset=utf-8') // 基于流的多次写操作 const originStream = new PassThrough() pipeline(originStream, zlib.createBrotliCompress(), res, (err) => { if (err) { console.error(err); } }) originStream.write(Buffer.from('<h1 id="BrotliCompress">BrotliCompress</h1>')) originStream.write(Buffer.from('<h2 id="测试数据">测试数据</h2>')) originStream.write(Buffer.from(testTxt)) originStream.end() return } res.end(testTxt) }] ] const route = routes.find(v => url.startsWith(v[0])) if (route) { route[1]() return } // 兜底 res.setHeader('Content-Type', 'text/html; charset=utf-8') res.end(`<h1 id="nbsp-url">404: ${url}</h1> <h2 id="已注册路由">已注册路由</h2> <ul> ${routes.map(r => `<li><a href="${r[0]}">${r[0]}</a></li>`).join('')} </ul> `) res.end() }) app.listen(3000)

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment supprimer un nœud avec nvm : 1. Téléchargez « nvm-setup.zip » et installez-le sur le lecteur C ; 2. Configurez les variables d'environnement et vérifiez le numéro de version via la commande « nvm -v » 3. Utilisez la commande « nvm » ; install" commande Installer le nœud ; 4. Supprimez le nœud installé via la commande "nvm uninstall".

Comment gérer le téléchargement de fichiers ? L'article suivant vous expliquera comment utiliser Express pour gérer les téléchargements de fichiers dans le projet de nœud. J'espère qu'il vous sera utile !

Durant cette période, je développais un service HTML dynamique commun à toutes les catégories de documents Tencent. Afin de faciliter la génération et le déploiement des accès aux différentes catégories, et pour suivre la tendance de migration vers le cloud, j'ai envisagé d'utiliser Docker pour corriger. contenu du service et gérer les versions des produits de manière unifiée. Cet article partagera l'expérience d'optimisation que j'ai accumulée en train de servir Docker pour votre référence.

Cet article partagera avec vous l'outil de gestion de processus de Node "pm2" et expliquera pourquoi pm2 est nécessaire, comment installer et utiliser pm2, j'espère qu'il sera utile à tout le monde !

Explication détaillée et guide d'installation pour les nœuds de pignon Cet article introduira l'écosystème de pignon en détail - nœuds PI, un rôle clé dans l'écosystème de pignon et fournir des étapes complètes pour l'installation et la configuration. Après le lancement du réseau de test de la blockchain pèse, les nœuds PI sont devenus une partie importante de nombreux pionniers participant activement aux tests, se préparant à la prochaine version du réseau principal. Si vous ne connaissez pas encore Pinetwork, veuillez vous référer à ce qu'est Picoin? Quel est le prix de l'inscription? PI Utilisation, exploitation minière et sécurité. Qu'est-ce que Pinetwork? Le projet Pinetwork a commencé en 2019 et possède sa pièce exclusive de crypto-monnaie PI. Le projet vise à en créer un que tout le monde peut participer

Comment empaqueter le fichier exécutable nodejs avec pkg ? L'article suivant vous expliquera comment utiliser pkg pour empaqueter un projet Node dans un fichier exécutable. J'espère qu'il vous sera utile !

npm node gyp a échoué car les versions de « node-gyp.js » et « Node.js » ne correspondaient pas. La solution : 1. Videz le cache du nœud via « npm cache clean -f » 2. Via « npm install - ». g n" Installez le module n ; 3. Installez la version "node v12.21.0" via la commande "n v12.21.0".

Qu'est-ce qu'un système d'authentification unique ? Comment l'implémenter en utilisant nodejs ? L'article suivant vous présentera comment utiliser Node pour implémenter un système d'authentification unique. J'espère qu'il vous sera utile !
