怎麼使用Node.js的http模組處理檔上傳?以下這篇文章就來看看伺服器端要如何處理前端上傳的文件,希望對大家有幫助!
如果我們現在向伺服器發送的資料如下圖所示,裡麵包含了普通的欄位訊息name
以及一個圖片檔案file
:
#我們先來看看如何在伺服器接收到檔案上傳的數據,並在調試控制台列印查看:
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 的模式來運行程式碼:
點擊"運行和調試" 後,vs code 就會幫我們把伺服器運行起來了:
之後當我們發送了上傳的請求,再點擊下圖右上角的"單步跳過",就可以看到請求的數據了—— 那些可以被ASCII 編譯的信息,比如英文字母,可以直接看到了,而圖片的數據則是一堆亂碼:
接下來就是處理取得的請求數據,將裡面的圖片數據截取出來然後透過寫入流產生圖片。
取得圖片資料
因為可讀流的'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
#,得到的資料如下:
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()
--------------------------158329774739626517859573是客戶端隨機產生的,用於分割表單裡的每段資料的分隔符號( boundary),在每個表單項目的開頭和結尾都有,並且在開頭處的前面都會加上兩個減號
--,在整個表單資料結束處的末尾也會加上兩個減號。檢視請求頭:
content-type 裡定義了
boundary,所以我們可以使用下列方法來取得分隔符:
const boundary = req.headers['content-type'].split('boundary=')[1]
產生圖片
# 取得了圖片資料imgData 後,就可以透過
fs 的writeFile() 寫入檔案產生圖片了:
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中文網其他相關文章!