首頁 > web前端 > js教程 > 主體

淺析Node中http模組怎麼處理檔案上傳

青灯夜游
發布: 2023-03-09 19:37:01
轉載
1649 人瀏覽過

怎麼使用Node.js的http模組處理檔上傳?以下這篇文章就來看看伺服器端要如何處理前端上傳的文件,希望對大家有幫助!

淺析Node中http模組怎麼處理檔案上傳

查看請求資料

如果我們現在向伺服器發送的資料如下圖所示,裡麵包含了普通的欄位訊息name 以及一個圖片檔案file

淺析Node中http模組怎麼處理檔案上傳

#我們先來看看如何在伺服器接收到檔案上傳的數據,並在調試控制台列印查看:

const http = require('http')
const server = http.createServer((req, res) => {
  req.setEncoding('binary')
  req.on('data', data => {
    console.log(data)
  })
  req.on('end', () => {
    console.log('上传结束')
    res.end('上传成功')
  })
})
server.listen(3010, () => console.log('服务器开启'))
登入後複製

想要能看懂列印的結果,我們透過req.setEncoding('binary') 設定了字元編碼為'binary' ,這樣得到的資料就不是buffer 物件而是ASCII 編碼後的字串,我們就可以用一些字串的方法來處理資料了。

但是當檔案大小比較大時,直接透過在命令列輸入 node 或 nodemon 來運行程式碼,得到的資料無法完全在控制台展示。所以我們可以在要列印請求資料的地方打上斷點,透過debugger 的模式來運行程式碼:

淺析Node中http模組怎麼處理檔案上傳

點擊"運行和調試" 後,vs code 就會幫我們把伺服器運行起來了:

淺析Node中http模組怎麼處理檔案上傳

之後當我們發送了上傳的請求,再點擊下圖右上角的"單步跳過",就可以看到請求的數據了—— 那些可以被ASCII 編譯的信息,比如英文字母,可以直接看到了,而圖片的數據則是一堆亂碼:

淺析Node中http模組怎麼處理檔案上傳

接下來就是處理取得的請求數據,將裡面的圖片數據截取出來然後透過寫入流產生圖片。

處理文件(圖片)資料

取得圖片資料

因為可讀流'data' 事件一次最多讀取64kb 的數據,當圖片比較大時,可能會觸發多次,所以我們定義變數reqData 來儲存請求發來的資料:

let reqData = ''
req.on('data', data => {
  reqData += data
})
req.on('end', () => {
  console.log(reqData) // 在这行打断点
  res.end('上传成功')
})
登入後複製

req 觸發了'end' 事件說明請求資料讀取完畢,如果在上列程式碼的第6 行console.log(reqData) 處打個斷點,然後查看reqData#,得到的資料如下:

淺析Node中http模組怎麼處理檔案上傳

##圖片的資料應該是

image/png\r\n\r\n\r\n------------------------ ----158329774739626517859573--\r\n 中間這段。我們可以去取得圖片資料的起(imgDataStartIndex)止(imgDataEndIndex)位置的index,然後使用substring() 做個截取,最後再使用trim() 方法去除首位的空格\r\n

const imgType = 'image/png'
const imgDataStartIndex = reqData.indexOf(imgType) + imgType.length
const imgDataEndIndex = reqData.indexOf(`--${boundary}--`)
const imgData = reqData.substring(imgDataStartIndex, imgDataEndIndex).trim()
登入後複製

取得分隔符號boundary

--------------------------158329774739626517859573是客戶端隨機產生的,用於分割表單裡的每段資料的分隔符號( boundary),在每個表單項目的開頭和結尾都有,並且在開頭處的前面都會加上兩個減號--,在整個表單資料結束處的末尾也會加上兩個減號。檢視請求頭:

淺析Node中http模組怎麼處理檔案上傳

可以發現在

content-type 裡定義了boundary,所以我們可以使用下列方法來取得分隔符:

const boundary = req.headers['content-type'].split('boundary=')[1]
登入後複製

產生圖片

# 取得了圖片資料

imgData 後,就可以透過fswriteFile() 寫入檔案產生圖片了:

fs.writeFile('./img.png', imgData, 'binary', err => {
  if (!err) console.log('图片写入成功')
})
登入後複製

#注意需要在第三個參數傳入

'binary' 來設定 encoding

總結

現將程式碼匯總如下:

const http = require('http')
const fs = require('fs')

const server = http.createServer((req, res) => {
  req.setEncoding('binary')
  const boundary = req.headers['content-type'].split('boundary=')[1]
  let reqData = ''
  req.on('data', data => {
    reqData += data
  })
  req.on('end', () => {
    const imgType = 'image/png'
    const imgDataStartIndex = reqData.indexOf(imgType) + imgType.length
    const imgDataEndIndex = reqData.indexOf(`--${boundary}--`)
    const imgData = reqData.substring(imgDataStartIndex, imgDataEndIndex).trim()
    fs.writeFile('./img.png', imgData, 'binary', err => {
      if (!err) console.log('图片写入成功')
    })
    res.end('上传成功')
  })
})

server.listen(3010, () => console.log('服务器开启'))
登入後複製

上述代码能够成功运行还有一些限制,比如只能处理单文件上传,且文件需要是 png 格式的图片,并且放在表单最后一项。文章的目的在于简单了解使用 node 的 http 模块搭建的服务器大体上是如何处理上传文件的请求的,为将来深入学习其它基于 http 模块的框架(express.js、koa.js 等)打好基础。

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

以上是淺析Node中http模組怎麼處理檔案上傳的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!