人妻精品在线观看一区二区三区,蜜臀av精品一区二区三区网站,中文一区二区三区亚洲欧美,熟女人妇精品一区二区,人妻av在线观看视频,欧美日韩国产三级精品网站,黄色免费网站直接进入,超碰公开福利正在播放,国产毛片乡下农村妇女毛片

淺析Node中http模塊怎么處理文件上傳-環(huán)球今亮點(diǎn)

來(lái)源:php中文網(wǎng) | 2023-03-09 19:46:29 |

怎么使用Node.js的http模塊處理文件上傳?下面本篇文章就來(lái)看看在服務(wù)器端要如何處理前端上傳的文件,希望對(duì)大家有所幫助!

查看請(qǐng)求數(shù)據(jù)

如果我們現(xiàn)在向服務(wù)器發(fā)送的數(shù)據(jù)如下圖所示,里面包含了普通的字段信息 name以及一個(gè)圖片文件 file


(相關(guān)資料圖)

我們先來(lái)看看如何在服務(wù)器接收到文件上傳的數(shù)據(jù),并在調(diào)試控制臺(tái)打印查看:

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("上傳結(jié)束")    res.end("上傳成功")  })})server.listen(3010, () => console.log("服務(wù)器開(kāi)啟"))

想要能看懂打印的結(jié)果,我們通過(guò) req.setEncoding("binary")設(shè)置了字符編碼為 "binary",這樣得到的數(shù)據(jù)就不是 buffer 對(duì)象而是 ASCII 編碼后的字符串,我們就可以使用一些字符串的方法來(lái)處理數(shù)據(jù)了。

但是當(dāng)文件大小比較大時(shí),直接通過(guò)在命令行輸入 node 或 nodemon 來(lái)運(yùn)行代碼,得到的數(shù)據(jù)無(wú)法完全在控制臺(tái)展示。所以我們可以在要打印請(qǐng)求數(shù)據(jù)的地方打上斷點(diǎn),通過(guò) debugger 的模式來(lái)運(yùn)行代碼:

點(diǎn)擊 "運(yùn)行和調(diào)試" 后,vs code 就會(huì)幫我們把服務(wù)器運(yùn)行起來(lái)了:

之后當(dāng)我們發(fā)送了上傳的請(qǐng)求,再點(diǎn)擊下圖右上角的 "單步跳過(guò)",就可以看到請(qǐng)求的數(shù)據(jù)了 —— 那些可以被 ASCII 編譯的信息,比如英文字母,可以直接看到了,而圖片的數(shù)據(jù)則是一堆亂碼:

接下來(lái)就是處理獲取的請(qǐng)求數(shù)據(jù),將里面的圖片數(shù)據(jù)截取出來(lái)然后通過(guò)寫入流生成圖片。

處理文件(圖片)數(shù)據(jù)

獲取圖片數(shù)據(jù)

因?yàn)榭勺x流的 "data"事件一次最多讀取 64kb 的數(shù)據(jù),當(dāng)圖片比較大時(shí),可能會(huì)觸發(fā)多次,所以我們定義變量 reqData來(lái)存儲(chǔ)請(qǐng)求發(fā)來(lái)的數(shù)據(jù):

let reqData = ""req.on("data", data => {  reqData += data})req.on("end", () => {  console.log(reqData) // 在這行打斷點(diǎn)  res.end("上傳成功")})

當(dāng) req觸發(fā)了 "end"事件說(shuō)明請(qǐng)求數(shù)據(jù)讀取完畢,如果在上列代碼的第 6 行 console.log(reqData)處打個(gè)斷點(diǎn),然后查看 reqData,得到的數(shù)據(jù)如下:

圖片的數(shù)據(jù)應(yīng)該是 image/png\r\n\r\n\r\n----------------------------158329774739626517859573--\r\n中間這段。我們可以去獲取圖片數(shù)據(jù)的起(imgDataStartIndex)止(imgDataEndIndex)位置的 index,然后使用 substring()做個(gè)截取,最后再使用 trim()方法去除首位的空格 \r\n

const imgType = "image/png"const imgDataStartIndex = reqData.indexOf(imgType) + imgType.lengthconst imgDataEndIndex = reqData.indexOf(`--${boundary}--`)const imgData = reqData.substring(imgDataStartIndex, imgDataEndIndex).trim()

獲取分隔符 boundary

--------------------------158329774739626517859573是客戶端隨機(jī)生成的,用于分割表單里的每段數(shù)據(jù)的分隔符(boundary),在每個(gè)表單項(xiàng)的開(kāi)頭和結(jié)尾都有,并且在開(kāi)頭處的前面都會(huì)加上兩個(gè)減號(hào) --,在整個(gè)表單數(shù)據(jù)結(jié)束處的末尾也會(huì)加上兩個(gè)減號(hào)。查看請(qǐng)求頭:

可以發(fā)現(xiàn)在 content-type里定義了boundary,于是我們可以使用如下方法獲取分隔符:

const boundary = req.headers["content-type"].split("boundary=")[1]

生成圖片

獲取到了圖片數(shù)據(jù) imgData后,就可以通過(guò) fs 的 writeFile()寫入文件生成圖片了:

fs.writeFile("./img.png", imgData, "binary", err => {  if (!err) console.log("圖片寫入成功")})

注意需要在第三個(gè)參數(shù)傳入"binary"來(lái)設(shè)定 encoding。

總結(jié)

現(xiàn)將代碼匯總?cè)缦拢?/p>

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("服務(wù)器開(kāi)啟"))

上述代碼能夠成功運(yùn)行還有一些限制,比如只能處理單文件上傳,且文件需要是 png 格式的圖片,并且放在表單最后一項(xiàng)。文章的目的在于簡(jiǎn)單了解使用 node 的 http 模塊搭建的服務(wù)器大體上是如何處理上傳文件的請(qǐng)求的,為將來(lái)深入學(xué)習(xí)其它基于 http 模塊的框架(express.js、koa.js 等)打好基礎(chǔ)。

更多node相關(guān)知識(shí),請(qǐng)?jiān)L問(wèn):nodejs 教程!

以上就是淺析Node中http模塊怎么處理文件上傳的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!

關(guān)鍵詞: