ホームページ  >  記事  >  ウェブフロントエンド  >  Nodejs に基づいて大きなファイルの HTTP 転送を実装するにはどうすればよいですか? (実践方法の共有)

Nodejs に基づいて大きなファイルの HTTP 転送を実装するにはどうすればよいですか? (実践方法の共有)

青灯夜游
青灯夜游転載
2022-01-17 19:16:383163ブラウズ

ベース node大きなファイルの http 送信を実装するにはどうすればよいですか?次の記事では、nodejs をベースにしたいくつかの実用的な http ファイル転送ソリューションを紹介します。

Nodejs に基づいて大きなファイルの HTTP 転送を実装するにはどうすればよいですか? (実践方法の共有)

nodejs に基づく http ファイル転送ソリューションは、現在のフロントエンドおよびバックエンドのフルスタック開発において重要な役割を果たしています。この記事では、大きなファイルの HTTP 転送を実装するためのいくつかのソリューションについて説明します。関数を実装する前に、まず、nodejs の fs モジュールを通じて大きなファイルを書き込み、プロジェクト内にローカル ファイルを生成します。

const fs = require('fs');
const writeStream = fs.createWriteStream(__dirname + "/file.txt");
for(let i = 0;i <= 100000; i++) {
  writeStream.write(`${i} —— 我是${i}号文件\n`, "utf-8");
}
writeStream.end();

Nodejs に基づいて大きなファイルの HTTP 転送を実装するにはどうすればよいですか? (実践方法の共有)

上記のコードが正常に実行された後、Aサイズ 3.2MB のテキスト ファイルが現在の実行ディレクトリに生成され、次のプログラムの「大きなファイル素材」として使用されます。大きなファイルの転送スキームをリストする前に、まず、後で使用する 2 つのパブリック メソッド、ファイル読み取りメソッドファイル圧縮メソッド:

// 封装读取文件的方法
const readFile = async (paramsData) => {
  return new Promise((resolve, reject) => {
    fs.readFile(paramsData, (err, data) => {
      if(err) {
        reject(&#39;文件读取错误&#39;);
      } else {
        resolve(data);
      }
    })
  })
}

// 封装文件压缩方法
const gzip = async (paramsData) => {
  return new Promise((resolve, reject) => {
    zlib.gzip(paramsData, (err, result) => {
      if(err) {
        reject(&#39;文件压缩错误&#39;);
      } else {
        resolve(result);
      }
    })
  })
}

## をカプセル化します。 #1. データ圧縮後に大きなファイルを送信する

ブラウザがリクエストを送信すると、

acceptaccept-*# が送信されます。 ## リクエスト ヘッダー情報。現在のブラウザでサポートされているファイル タイプ、サポートされている圧縮形式のリスト、およびサポートされている言語をサーバーに伝えるために使用されます。リクエスト ヘッダーの Accept-Encoding フィールドは、クライアントが理解できるコンテンツ エンコード方式 (通常は特定の圧縮アルゴリズム) をサーバーに伝えるために使用されます。サーバーはクライアントによってサポートされているメソッドを選択し、応答ヘッダー Content-Encoding を通じてその選択をクライアントに通知します。応答ヘッダーは、返された JS スクリプトが gzip## に渡されることをブラウザーに伝えます。 # 処理された圧縮アルゴリズム

// 请求头
accept-encoding: gzip, deflate, br
// 响应头
cache-control: max-age=2592000 
content-encoding: gzip 
content-type: application/x-javascript
Accept-Encoding

フィールドと

Content-Encoding フィールドの理解に基づいて、それがオンになっていないことを確認しましょう gzip そして gzip をオンにした場合の効果。

// 实现一个简单的文件读取服务器(没有开启gzip)
const server = http.createServer(async (req, res) => {
  res.writeHead(200, {
    "Content-Type": "text/plain;charset=utf-8",
  });
  const buffer = await readFile(__dirname + &#39;/file.txt&#39;);
  res.write(buffer);
  res.end();
})
server.listen(3000, () => {
  console.log(`server启动成功`)
})

// 实现一个简单的文件读取服务器(开启gzip)
const server = http.createServer(async(req, res) => {
  res.writeHead(200, {
    "Content-Type": "text/plain;charset=utf-8",
    "Content-Encoding": "gzip"
  });
  const buffer = await readFile(__dirname + &#39;/file.txt&#39;);
  const gzipData = await gzip(buffer);
  res.write(gzipData);
  res.end();
})
server.listen(3000, () => {
  console.log(`server启动成功`)
})

Nodejs に基づいて大きなファイルの HTTP 転送を実装するにはどうすればよいですか? (実践方法の共有)

Nodejs に基づいて大きなファイルの HTTP 転送を実装するにはどうすればよいですか? (実践方法の共有)

2. データ チャンクによる送信

データベース クエリから取得したデータを使用して大規模な HTML テーブルを生成する必要があるシナリオ、または大量の画像を送信する必要がある場合、これはブロック送信によって実現できます。

Transfer-Encoding: chunked
Transfer-Encoding: gzip, chunked

応答ヘッダーの

Transfer-Encoding

フィールドの値は

chunked で、データが一連のチャンクで送信されることを示します。 2 つのフィールド Transfer-EncodingContent-Length は相互に排他的であることに注意してください。つまり、これら 2 つのフィールドは応答メッセージ内に同時に出現することはできません。

// 数据分块传输
const spilitChunks = async () =>{
  const buffer = await readFile(__dirname + &#39;/file.txt&#39;);
  const lines = buffer.toString(&#39;utf-8&#39;).split(&#39;\n&#39;);
  let [chunks, i, n] = [[], 0, lines.length];
  while(i < n) {
    chunks.push(lines.slice(i, i+= 10));
  };
  return chunks;
}
const server = http.createServer(async(req, res) => {
  res.writeHead(200, {
    "Content-Type": "text/plain;charset=utf-8",
    "Transfer-Encoding": "chunked",
    "Access-Control-Allow-Origin": "*",
  });
  const chunks = await spilitChunks();
  for(let i =0; i< chunks.length; i++) {
    setTimeout(() => {
      let content = chunks[i].join("&");
      res.write(`${content.length.toString(16)}\r\n${content}\r\n`);
    }, i * 1000);
  }
  setTimeout(() => {
    res.end();
  }, chunks.length * 1000);
})
server.listen(3000, () => {
  console.log(`server启动成功`)
})

3. データ ストリーム経由で送信

Node.js

を使用する場合 大きなファイルをクライアントに返す を使用する場合ストリームを使用してファイル ストリームを返すと、大きなファイルを処理するときに大量のメモリを消費することを避けることができます。具体的な実装は以下の通りです。ストリーム形式を使用してファイル データを返す場合、HTTP 応答ヘッダーの

Transfer-Encoding フィールドの値は chunked となり、データが一連のチャンクで送信されることを示します。

const server = http.createServer((req, res) => {
  res.writeHead(200, {
    "Content-Type": "text/plain;charset=utf-8",
    "Content-Encoding": "gzip",
    "Transfer-Encoding": "chunked"
  });
  fs.createReadStream(__dirname + "/file.txt")
    .setEncoding("utf-8")
    .pipe(zlib.createGzip())
    .pipe(res);
})

server.listen(3000, () => {
  console.log(`server启动成功`)
})
ノード関連の知識については、nodejs チュートリアル

を参照してください。 !

以上がNodejs に基づいて大きなファイルの HTTP 転送を実装するにはどうすればよいですか? (実践方法の共有)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。