用Node处置惩罚文件上传

媒介

在Web开辟中,文件上传是一个异常罕见、异常主要的功用。本文将引见如何用Node处置惩罚上传的文件。

需求剖析

由于如今前后端星散很盛行,那末本文也直接采纳前后端星散的做法。前端界面以下:
《用Node处置惩罚文件上传》

用户从浏览器中挑选文件,点击上传,将提议http要求到效劳器,效劳器将接受到的文件存储在效劳器硬盘中。

前端部份

ajax要求库采纳axios,为了简化申明,前端限定上传的文件范例只能为图片,且一次只能上传一张,有兴致的朋侪可以自行补充,代码以下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
  <input type="file" name="file" accept="image/*" onchange="changeImg(event)"/>
  <button onclick="submit()">上传</button>

  <script>
    let file = ''
    let fileName = ''

    function submit() {
      let data = new FormData()
      data.append('imgName', fileName)
      data.append('img', file)

      axios({
        method: 'post',
        timeout: 2000,
        url: 'http://localhost:3000/postApi',
        data: data
      })
        .then(response => {
          console.log(response.data)
        })
        .catch(error => {
          console.log(error)
        })
    }

    function changeImg(e) {
      file = e.target.files.item(0)
      // 假如不挑选图片
      if (file === null) {
        return
      }
      fileName = file.name
    }
  </script>
</body>
</html>

后端部份

这是本文要引见的重点,为了用高效流通的体式格局来剖析文件上传要求,我们先引入formidable库:

npm install formidable --save

formidable的流式剖析器让它成为了处置惩罚文件上传的绝佳挑选,也就是说它能跟着数据块的上传吸收它们,剖析它们,并吐出特定的部份,置信熟习流的朋侪会很好明白。这类体式格局不仅快,还不会由于须要大批缓冲而致使内存膨胀,即使像视频这类大型文件,也不会把历程压垮。
起首,我们在根目录下建立myImage文件,用于寄存上传的图片(注重:假如没有建立,会致使上传报错),接着,我们建立一个IncomingForm实例form,而且设置寄存途径为myImage文件夹。代码以下:

var http = require('http')
var formidable = require('formidable')

var server = http.createServer(function(req, res){
  // 1 设置cors跨域
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
  res.setHeader('Content-Type', 'application/json')

  // 2
  switch (req.method) {
    case 'OPTIONS':
      res.statusCode = 200
      res.end()
      break
    case 'POST':
      upload(req, res)
      break
  }
})

function upload(req, res) {
  // 1 推断
  if (!isFormData(req)) {
    res.statusCode = 400
    res.end('毛病的要求, 请用multipart/form-data花样')
    return
  }

  // 2 处置惩罚
  var form = new formidable.IncomingForm()
  form.uploadDir = './myImage'
  form.keepExtensions = true

  form.on('field', (field, value) => {
    console.log(field)
    console.log(value)
  })
  form.on('end', () => {
    res.end('上传完成!')
  })

  form.parse(req)
}

function isFormData(req) {
  let type = req.headers['content-type'] || ''
  return type.includes('multipart/form-data')
}

server.listen(3000)
console.log('port is on 3000.')

node app开启http效劳器后,在前端页面中上传一张kitty.jpg,我们看到控制台打印出了前端上传的imgName属性:kitty.jpg
《用Node处置惩罚文件上传》

而且,myImage文件夹目录下多了一张图片:
《用Node处置惩罚文件上传》

翻开一看,恰是夙昔端上传的那张kitty.jpg

文件更名

我们发明,这个默许的文件称号并非我们想要的,我们想改成以当前时刻戳定名的文件,增加的功用代码以下:

  var fs = require('fs')

  form.on('file', (name, file) => {
    // 重定名文件
    let types = file.name.split('.')
    let suffix = types[types.length - 1]
    fs.renameSync(file.path, './myImage/' + new Date().getTime() + '.' + suffix)
  })

再次上传,发明如今存的照片称号已变成我们想要的花样了。
《用Node处置惩罚文件上传》

增加上传进度

Formidable的progress事宜能给出收到的字节数,以及希冀收到的字节数。我们可以借助这个做出一个进度条。
我们为上面的顺序增加下面的代码,每次有progress事宜引发,就会盘算百分比并用console.log()输出:

  form.on('progress', (bytesReceived, bytesExpected) => {
    var percent = Math.floor(bytesReceived / bytesExpected * 100)
    console.log(percent)
  })

再次上传一张图片,如今控制台已会打印出进度显现了:
《用Node处置惩罚文件上传》

固然,平常情况下,我们是要把这个进度传回到用户的浏览器中去,这关于任何想要上传大型文件的顺序来说是个很棒的特征,而且这是个很适合用Node完成的使命。比如说用WebSocket协定,或许像Socket.IO如许的及时模块,关于Node中运用websocket,背面我会单独出一篇文章来引见。

毛病处置惩罚

任何时刻都不要忘了对顺序增加毛病处置惩罚,假如你的顺序在主要的时刻崩掉了,可以轻则被老板打屁股,重则拉出去祭天。设想一下,假如用户上传的图片很大,而且用户的收集还很慢,那末上传的时刻会超越前端代码中设置的要求超时时刻2s,效劳器就会崩掉,不信?我们来试一下。
起首,我挑选了一张很大的图片,5M,而且用chrome浏览器将浏览器收集环境设置为slow 3g,设置要领以下:
f12翻开开辟者东西,在more tools–network conditions
《用Node处置惩罚文件上传》

《用Node处置惩罚文件上传》

点击上传,我们瞥见效劳端控制台的信息以下,效劳器崩掉了:
《用Node处置惩罚文件上传》

所以,末了我们加上了毛病处置惩罚,代码以下:

  // 加上毛病处置惩罚,防备用户收集慢,或许作废上传,致使效劳器崩掉
  form.on('error', err => {
    console.log(err)
    res.statusCode = 500
    res.end('效劳器内部毛病!')
  })

小结

如今,置信你已学会了如何用Node处置惩罚文件上传了,连系前面的那篇用Node供应静态文件效劳的文章,你是否是可以本身探索着去尝试做一些风趣的事变了呢?

参考浏览

formidable文档
input的file范例的accept属性

    原文作者:moddx
    原文地址: https://segmentfault.com/a/1190000015558975
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞