Rumah >hujung hadapan web >tutorial js >Bagaimana untuk melaksanakan pemindahan HTTP fail besar berdasarkan nodejs? (Perkongsian kaedah praktikal)

Bagaimana untuk melaksanakan pemindahan HTTP fail besar berdasarkan nodejs? (Perkongsian kaedah praktikal)

青灯夜游
青灯夜游ke hadapan
2022-01-17 19:16:383312semak imbas

Bagaimana untuk melaksanakan pemindahan HTTP bagi fail besar berdasarkan nod? Artikel berikut akan memperkenalkan kepada anda beberapa penyelesaian pemindahan fail http yang praktikal berdasarkan nodejs Saya harap ia akan membantu anda!

Bagaimana untuk melaksanakan pemindahan HTTP fail besar berdasarkan nodejs? (Perkongsian kaedah praktikal)

Penyelesaian pemindahan fail http berdasarkan nodejs memainkan peranan penting dalam pembangunan tindanan penuh hadapan dan belakang dalam hal ini artikel, saya akan melalui beberapa penyelesaian A untuk merealisasikan penghantaran HTTP fail besar. Sebelum melaksanakan fungsi, kami mula-mula menulis fail besar melalui modul fs nodejs dan menjana fail setempat dalam projek:

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();

Bagaimana untuk melaksanakan pemindahan HTTP fail besar berdasarkan nodejs? (Perkongsian kaedah praktikal)

Selepas kod di atas berjalan dengan jayanya , fail teks dengan saiz 3.2MB akan dijana dalam direktori pelaksanaan semasa, yang akan digunakan sebagai "bahan fail besar" untuk program berikut. Sebelum menyenaraikan skema pemindahan fail besar, kami mula-mula merangkum dua kaedah awam yang akan digunakan kemudian: 文件读取方法 dan 文件压缩方法:

// 封装读取文件的方法
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. Melalui fail besar Dihantar selepas pemampatan data

Apabila penyemak imbas menghantar permintaan, ia akan membawa accept dan accept-* maklumat pengepala permintaan, yang digunakan untuk memberitahu pelayan jenis fail yang disokong oleh semasa penyemak imbas, Senarai format mampatan yang disokong dan bahasa yang disokong. Medan Accept-Encoding dalam pengepala permintaan digunakan untuk memberitahu pelayan kaedah pengekodan kandungan (biasanya algoritma pemampatan tertentu) yang boleh difahami oleh pelanggan. Pelayan akan memilih kaedah yang disokong oleh klien dan memberitahu klien tentang pilihan tersebut melalui pengepala respons Content-Encoding Pengepala respons memberitahu penyemak imbas bahawa skrip JS yang dikembalikan telah diproses oleh gzip algoritma pemampatan

<.>
// 请求头
accept-encoding: gzip, deflate, br
// 响应头
cache-control: max-age=2592000 
content-encoding: gzip 
content-type: application/x-javascript
Berdasarkan pemahaman medan

dan Accept-Encoding, mari sahkan kesan tidak menghidupkan Content-Encoding dan menghidupkan 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启动成功`)
})

Bagaimana untuk melaksanakan pemindahan HTTP fail besar berdasarkan nodejs? (Perkongsian kaedah praktikal)

// 实现一个简单的文件读取服务器(开启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启动成功`)
})

Bagaimana untuk melaksanakan pemindahan HTTP fail besar berdasarkan nodejs? (Perkongsian kaedah praktikal)

2. Penghantaran melalui data chunking

Apabila terdapat senario di mana jadual HTML yang besar perlu dijana menggunakan data yang diperoleh daripada pertanyaan pangkalan data, atau apabila sejumlah besar imej perlu dihantar, ini boleh dicapai melalui penghantaran blok.

Transfer-Encoding: chunked
Transfer-Encoding: gzip, chunked
Nilai medan

dalam pengepala respons ialah Transfer-Encoding, menunjukkan bahawa data dihantar dalam satu siri ketulan. Perlu diingatkan bahawa kedua-dua medan chunked dan Transfer-Encoding adalah saling eksklusif, yang bermaksud bahawa kedua-dua medan ini tidak boleh muncul pada masa yang sama dalam mesej respons. Content-Length

// 数据分块传输
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 Hantar melalui aliran data

Apabila menggunakan

untuk mengembalikan fail besar kepada klien, gunakan strim Returning aliran fail dalam bentuk boleh mengelakkan daripada menduduki terlalu banyak memori semasa memproses fail besar. Pelaksanaan khusus adalah seperti berikut. Apabila menggunakan strim untuk mengembalikan data fail, nilai medan pengepala respons HTTP Node.js ialah Transfer-Encoding, menunjukkan bahawa data dihantar dalam satu siri ketulan. 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启动成功`)
})
Untuk lebih banyak pengetahuan berkaitan nod, sila lawati:

tutorial nodejs! !

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan pemindahan HTTP fail besar berdasarkan nodejs? (Perkongsian kaedah praktikal). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam