分享更有价值
被信任是一种快乐

Node中http模块如何处理文件上传

文章页正文上

本文小编为大家详细介绍“Node中http模块如何处理文件上传”,内容详细,步骤清晰,细节处理妥当,希望这篇“Node中http模块如何处理文件上传”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。 如果我们现在向服务器发送的数据如下图所示,里面包含了普通的字段信息 name 以及一个图片文件 file:我们先来看看如何在服务器接收到文件上传的数据,并在调试控制台打印查看:

consthttp=require('http')
constserver=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 来存储请求发来的数据:

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

req 触发了 'end' 事件说明请求数据读取完毕,如果在上列代码的第 6 行 console.log(reqData) 处打个断点,然后查看 reqData,得到的数据如下:图片的数据应该是 image/pngrnrnrn----------------------------158329774739626517859573--rn 中间这段。我们可以去获取图片数据的起(imgDataStartIndex)止(imgDataEndIndex)位置的 index,然后使用 substring() 做个截取,最后再使用 trim() 方法去除首位的空格 rn

constimgType='image/png'
constimgDataStartIndex=reqData.indexOf(imgType)+imgType.length
constimgDataEndIndex=reqData.indexOf(`--${boundary}--`)
constimgData=reqData.substring(imgDataStartIndex,imgDataEndIndex).trim()

--------------------------158329774739626517859573是客户端随机生成的,用于分割表单里的每段数据的分隔符(boundary),在每个表单项的开头和结尾都有,并且在开头处的前面都会加上两个减号 --,在整个表单数据结束处的末尾也会加上两个减号。查看请求头:可以发现在 content-type 里定义了boundary,于是我们可以使用如下方法获取分隔符:

constboundary=req.headers['content-type'].split('boundary=')[1]

生成图片获取到了图片数据 imgData 后,就可以通过 fs 的 writeFile() 写入文件生成图片了:

fs.writeFile('./img.png',免费云主机、域名imgData,'binary',err=>{
if(!err)console.log('图片写入成功')
})

注意需要在第三个参数传入'binary' 来设定 encoding 。现将代码汇总如下:

consthttp=require('http')
constfs=require('fs')

constserver=http.createServer((req,res)=>{
req.setEncoding('binary')
constboundary=req.headers['content-type'].split('boundary=')[1]
letreqData=''
req.on('data',data=>{
reqData+=data
})
req.on('end',()=>{
constimgType='image/png'
constimgDataStartIndex=reqData.indexOf(imgType)+imgType.length
constimgDataEndIndex=reqData.indexOf(`--${boundary}--`)
constimgData=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中http模块如何处理文件上传”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注云技术行业资讯频道。

相关推荐: vue input金额如何转大写

本篇内容主要讲解“vue input金额如何转大写”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue input金额如何转大写”吧! 实现思路该组件实现的主要思路是,通过监听 input 输入框的值变化,获取输入…

文章页内容下
赞(0) 打赏
版权声明:本站采用知识共享、学习交流,不允许用于商业用途;文章由发布者自行承担一切责任,与本站无关。
文章页正文下
文章页评论上

云服务器、web空间可免费试用

宝塔面板主机、支持php,mysql等,SSL部署;安全高速企业专供99.999%稳定,另有高防主机、不限制内容等类型,具体可咨询QQ:360163164,Tel同微信:18905205712

主机选购导航云服务器试用

登录

找回密码

注册