目次
事前知識
accept-encoding
Node.js には、
コマンドを使用して、解凍前後の結果を直接カウントします。
# createGzip および createUnzip
gzip および unzip
基于流(stream)操作
基于Buffer操作
Node Server中的实践
BrotliCompress
测试数据
404: ${url}
已注册路由
ホームページ ウェブフロントエンド jsチュートリアル Node を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょう

Node を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょう

Mar 08, 2022 pm 08:00 PM
node

Nodejs を使用してコンテンツ圧縮を実現するにはどうすればよいですか?以下の記事では、Node側でコンテンツ圧縮(gzip/br/deflate)を実装する方法を実践しながら解説していきますので、ご参考になれば幸いです。

Node を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょう

アプリケーションのログを確認すると、ログ ページに入ってからロードするのに常に数秒かかることがわかりました (インターフェイスはページ分割されていません)。そこで、ネットワーク パネルを開いて、

Node を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょう

Node を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょう

# を確認したところ、インターフェイスから返されたデータが圧縮されていないことがわかりました。インターフェイスには Nginx リバース プロキシが使用されていると考えられました。Nginx はこのレイヤーの実行を自動的に支援します (これについては後で検討します。理論的には実現可能です)

ここでのバックエンドは Node Service

です。

この記事では、HTTP データ圧縮関連の知識と ノード側での実践を共有します

事前知識

次の内容クライアントはすべてブラウジングを指します

accept-encoding

Node を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょう

クライアントがサーバーへのリクエストを開始すると、リクエストに ## が追加されます#accept-encoding フィールドの値は、クライアントがサポートする圧縮コンテンツ エンコーディング 形式 content-encoding

Node を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょう を示します。

サーバーは、返されたコンテンツの圧縮を実行した後、応答ヘッダーに

content-encoding を追加することで、コンテンツの実際の圧縮に使用されるエンコード アルゴリズム をブラウザーに伝えます。 deflate/gzip/br

deflate

は、LZ77 アルゴリズムと ハフマン コーディング ロスレス データ圧縮アルゴリズムの両方を使用するものです。

gzip

は、DEFLATE に基づくアルゴリズムです。

br

は、データ Brotli を参照します。 format 圧縮率をさらに向上させることを目的として、テキストを圧縮すると、deflate に比べて圧縮密度が 20% 増加しますが、圧縮速度と解凍速度はほぼ変わりません zlib module

Node.js には、

Gzip

Deflate/InflateBrotli へのアクセスを提供する zlib モジュールが含まれています 実装された圧縮関数 ここでは

gzip

を例に、シナリオに応じたさまざまな利用方法を列挙します。 Brotli ですが、API は異なります stream

に基づく操作

Node を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょう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`
ログイン後にコピー
Node を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょうファイルを解凍/圧縮する

Unzip/ 圧縮結果を表示するには、ここで

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(stream)## に基づく操作

# createGzip および createUnzip

注: 明示的に同期される API を除く、すべての zlib API , Node.js の内部スレッド プールを使用します。非同期とみなされます

    したがって、次の例の圧縮コードと解凍コードは別々に実行する必要があります。そうしないとエラーが報告されます
  • 方法 1:
  • サンプルを直接使用する
  • // 压缩
    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)
    ログイン後にコピー

pipe メソッドを使用する 方法 2: pipeline

を使用する

stream で返される 他の処理を個別に実行する

// 压缩
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: Promiseizationpipeline

Method

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);
    })
ログイン後にコピー
Operation Buffer

gzip および unzip

API に基づいて、これら 2 つのメソッドには

synchronousasynchronous# が含まれます##types 圧縮gzip

    • gzipSync
    • 解凍
    • unzip
  • ##unzipSync
    • 方法 1:
    • readStreamTransfer
    • 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: synchronous
// 压缩
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)

// 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)
ログイン後にコピー
ログイン後にコピー

然后直接使用同步API进行转换,这里result就是压缩后的内容

const result = zlib.gzipSync(buffer)
ログイン後にコピー

可以写入文件,在HTTP Server中也可直接对压缩后的内容进行返回

fs.writeFileSync(targetFile, result)
ログイン後にコピー

Node Server中的实践

这里直接使用Node中 http 模块创建一个简单的 Server 进行演示

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

Node を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょう

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(&#39;<h1 id="BrotliCompress">BrotliCompress</h1>&#39;))
                originStream.write(Buffer.from(&#39;<h2 id="测试数据">测试数据</h2>&#39;))
                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(&#39;Content-Type&#39;, &#39;text/html; charset=utf-8&#39;)
    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(&#39;&#39;)}
    </ul>
    `)
    res.end()
})

app.listen(3000)
ログイン後にコピー

更多node相关知识,请访问:nodejs 教程

以上がNode を使用してコンテンツ圧縮を実現する方法を実践しながら話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

nvmでノードを削除する方法 nvmでノードを削除する方法 Dec 29, 2022 am 10:07 AM

nvm でノードを削除する方法: 1. 「nvm-setup.zip」をダウンロードして C ドライブにインストールします; 2. 「nvm -v」コマンドで環境変数を構成し、バージョン番号を確認します; 3. 「nvm」を使用しますinstall" コマンド ノードのインストール; 4. "nvm uninstall" コマンドでインストールしたノードを削除します。

Express を使用してノード プロジェクトでファイルのアップロードを処理する方法 Express を使用してノード プロジェクトでファイルのアップロードを処理する方法 Mar 28, 2023 pm 07:28 PM

ファイルのアップロードをどのように処理するか?次の記事では、Express を使用してノード プロジェクトでファイルのアップロードを処理する方法を紹介します。

NodeサービスのDockerミラーリングを行うにはどうすればよいですか?極限最適化の詳しい説明 NodeサービスのDockerミラーリングを行うにはどうすればよいですか?極限最適化の詳しい説明 Oct 19, 2022 pm 07:38 PM

この期間中、私は Tencent ドキュメントのすべてのカテゴリに共通する HTML 動的サービスを開発していましたが、さまざまなカテゴリへのアクセスの生成と展開を容易にし、クラウド移行のトレンドに従うために、Docker を使用して修正することを検討しました。サービス内容や製品バージョンを一元管理します。この記事では、私が Docker を提供するプロセスで蓄積した最適化の経験を参考として共有します。

Nodeのプロセス管理ツール「pm2」を徹底分析 Nodeのプロセス管理ツール「pm2」を徹底分析 Apr 03, 2023 pm 06:02 PM

この記事では、Node のプロセス管理ツール「pm2」について説明し、pm2 が必要な理由、pm2 のインストール方法と使用方法について説明します。皆様のお役に立てれば幸いです。

PIノードティーチング:PIノードとは何ですか? PIノードをインストールしてセットアップする方法は? PIノードティーチング:PIノードとは何ですか? PIノードをインストールしてセットアップする方法は? Mar 05, 2025 pm 05:57 PM

ピン張りのノードの詳細な説明とインストールガイドこの記事では、ピネットワークのエコシステムを詳細に紹介します - PIノードは、ピン系生態系における重要な役割であり、設置と構成の完全な手順を提供します。 Pinetworkブロックチェーンテストネットワークの発売後、PIノードは多くの先駆者の重要な部分になり、テストに積極的に参加し、今後のメインネットワークリリースの準備をしています。まだピン張りのものがわからない場合は、ピコインとは何かを参照してください。リストの価格はいくらですか? PIの使用、マイニング、セキュリティ分析。パインワークとは何ですか?ピン競技プロジェクトは2019年に開始され、独占的な暗号通貨PIコインを所有しています。このプロジェクトは、誰もが参加できるものを作成することを目指しています

pkg を使用して Node.js プロジェクトを実行可能ファイルにパッケージ化する方法について説明します。 pkg を使用して Node.js プロジェクトを実行可能ファイルにパッケージ化する方法について説明します。 Dec 02, 2022 pm 09:06 PM

Nodejs実行可能ファイルをpkgでパッケージ化するにはどうすればよいですか?次の記事では、pkg を使用して Node プロジェクトを実行可能ファイルにパッケージ化する方法を紹介します。

Angular と Node を使用したトークンベースの認証 Angular と Node を使用したトークンベースの認証 Sep 01, 2023 pm 02:01 PM

認証は、Web アプリケーションの最も重要な部分の 1 つです。このチュートリアルでは、トークンベースの認証システムと、それが従来のログイン システムとどのように異なるかについて説明します。このチュートリアルを終えると、Angular と Node.js で書かれた完全に動作するデモが表示されます。従来の認証システム トークンベースの認証システムに進む前に、従来の認証システムを見てみましょう。ユーザーはログイン フォームにユーザー名とパスワードを入力し、[ログイン] をクリックします。リクエストを行った後、データベースにクエリを実行してバックエンドでユーザーを認証します。リクエストが有効な場合、データベースから取得したユーザー情報を使用してセッションが作成され、セッション情報が応答ヘッダーで返され、セッション ID がブラウザに保存されます。対象となるアプリケーションへのアクセスを提供します。

IDEA で Node.js を構成してインストールするにはどうすればよいですか?メソッドの簡単な分析 IDEA で Node.js を構成してインストールするにはどうすればよいですか?メソッドの簡単な分析 Dec 21, 2022 pm 08:28 PM

IDEA でノードを実行するにはどうすればよいですか?次の記事では、IDEA で Node.js を構成、インストール、実行する方法を紹介します。

See all articles