怎麼使用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相關知識,請存取:!
以上就是淺析Node中http模組怎麼處理檔案上傳的詳細內容,更多請關注TW511.COM其它相關文章!