前端文件上传+expressJs后端文件写入

多文件选择

<input type="file" multiple />

下面以单文件为例

方式1:前端FormData + 后端multiparty

前端

//第一种:通过form表单
<form action="/" method="post" enctype="multipart/form-data">
  <input type="file" name="file" />
  <input type="text" name="filename" />
  <input type="submit" value="提交" />
</form>

//第二种:通过FormData
_file是通过<input type='file' />获得的文件
upload_btn_upload.addEventListener('click', function () {
  if (!_file) {
    console.error('has not select file~~');
    return
  }
  let formData = new FormData()
  //前端传入file,filename
  formData.append('file', _file)
  formData.append('filename', _file.name)
  axios.post('/', formData).then(data => {
    console.log(data);
  }).catch(reson => {
    throw reson
  })
})

后端

npm i multiparty
/*
multiparty插件的作用
1. 来解析前端传递的FormData格式数据
2. 将解析的文件起一个名字
3. 将文件保存在指定目录
*/

const multiparty = require('multiparty')

const formidable_upload = (req) => {
  return new Promise((resolve, reject) => {
    //multyparty的配置
    const config = {
      uploadDir: path.join(__dirname, '../img') //文件写入的目录
    }
    new multiparty.Form(config).parse(req, (err, fields, files) => {
      if (err) {
        reject(err)
        return
      }
      resolve({ fields, files })
    })
  })
}

index.post('/', async (req, res, next) => {
  try {
    let { fields, files } = await formidable_upload(req)
    let file = files.file || {}
    res.send({ code: 0, codeText: 'upload_success' })
  } catch (err) {
    res.send({ code: 1, codeText: err })
  }
});

multiparty换名字

new multiparty.Form(config).parse(req, (err, fields, files) => {
  fs.rename(files.file[0].path, path.join(__dirname, '../img/newName.jpg'), (err) => {})      
})

方法二:base64(只适用于图片)后端spark—md5解码

前端

let upload = document.getElementById('upload2')
  , upload_inp = upload.querySelector('.upload_inp')//<input tyype='file' />

let base64 = null

const FileToBase64 = (file) => {
  let reader = new FileReader()
  return new Promise((resolve) => {
    reader.readAsDataURL(file)
    reader.onload = function () {
      resolve(reader.result)
    }
  })
}
upload_inp.addEventListener('change', async function () {
  let file = this.files[0]

  let base64 = FileToBase64(file)

  instance.post('/upload_base64', {
    //用encodeURIComponent处理一下,防止乱码
    file: encodeURIComponent(base64)
    , filename: file.name
    }, {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
  })
})

后端

npm i spark-md5

const writeFile = (res, path, file, filename) => {
  return new Promise((resolve, reject) => {
    fs.writeFile(path, file, (err) => {
      if (err) {
        reject(err)
        res.send({
          code: 1
	  , codeText: '写入失败'
        })
        return
     }
     resolve()
     res.send({
        code: 0
        , codeText: '上传成功'
    })
})

index.post('/upload_base64', (req, res, next) => {
  let file = req.body.file
    , filename = req.body.filename
    , spark = new SparkMD5.ArrayBuffer()
    , suffix = /\.([0-9a-zA-Z]+)$/.exec(filename)[1]  //后缀
    , uploadDir = path.join(__dirname, '../img');

  //解码
  file = decodeURIComponent(file)
  //去base64前缀
  file = file.replace(/^data:image\/w+;base64,/, '')
  //转buffer格式数据
  file = Buffer.from(file, 'base64')
  //根据file的内容生成唯一的Hash文件名,同一(不同)张图片生成的Hash名一定是一样(不同)的
  spark.append(file)
  //spark.end()就是spark.append(file)的file生成的hash文件名
  let savePath = `${uploadDir}/${spark.end()}.${suffix}`
  writeFile(res, savePath, file, filename)
})

posted on   In-6026  阅读(118)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示