首頁  >  文章  >  web前端  >  基於nodejs如何實作http傳輸大檔案? (實踐方法分享)

基於nodejs如何實作http傳輸大檔案? (實踐方法分享)

青灯夜游
青灯夜游轉載
2022-01-17 19:16:383242瀏覽

基於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傳輸大檔案? (實踐方法分享)

以上程式碼成功運行後,在目前的執行目錄下將會產生一個大小為 3.2MB 大小的文字文件,該文件將作為下列方案的「大檔案素材」。在列出大檔案傳輸方案之前,我們先封裝後面即將使用的兩個公共方法: 檔案讀取方法檔案壓縮方法

// 封装读取文件的方法
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. 透過大檔案在資料壓縮後傳送

瀏覽器在發送請求時,都會攜帶 accept 和 accept- * 請求標頭訊息,用於告訴伺服器目前瀏覽器支援的檔案類型、支援的壓縮格式清單和支援的語言。請求頭中的 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启动成功`)
})

基於nodejs如何實作http傳輸大檔案? (實踐方法分享)

// 实现一个简单的文件读取服务器(开启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傳輸大檔案? (實踐方法分享)

#2. 透過資料分塊傳輸

有場景需要用從資料庫中查詢獲得的資料產生一個大的HTML 表格的時候,或者需要傳輸大量的圖片的時候,可以透過分塊傳輸實現。

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

回應頭 Transfer-Encoding 欄位的值為 chunked,表示資料以一系列分塊的形式進行傳送。要注意的是 Transfer-Encoding 和 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. 透過資料流的形式傳輸

#當使用 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启动成功`)
})

更多node相關知識,請造訪:nodejs 教學! !

以上是基於nodejs如何實作http傳輸大檔案? (實踐方法分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除