淘先锋技术网

首页 1 2 3 4 5 6 7

文件上传

使用的是 express 搭建的 nodejs 服务器

form 表单

注意设置 enctype: multipart/form-data 属性,否则服务器将无法正确解析表单数据

<form action="/api/upload" method="POST" enctype="multipart/form-data">
    <p>
      <input type="file" name="img123" accept="image/*">
    </p>
    <p>
      <input type="text" name="text">
    </p>
    <p>
      <button type="submit">提交</button>
    </p>
  </form>

formData

客户端

  1. 创建 formData 对象,new FormData

  2. 添加选择的文件

  3. 发送 fetch 请求 注意: fetch Api 的服务器响应必须是 json 格式,其他格式会出错!

  4. 把上传后的图片地址赋值给 img 的 src

<p>
    <input type="file" name="img" accept="image/*">
  </p>
  <p>
    <input type="text" name="img">
  </p>
  <p>
    <button type="submit">提交</button>
  </p>
  <img src="" alt="" id="resp">
function upload() {
  const formData = new FormData()
  const inpImg = document.querySelector('input[name=img]')
  const inpText = document.querySelector('input[name=text]')
  const img = document.getElementById('img')

  formData.append('text', inpText.value)

  for (const file of inpImg.files) {
    formData.append('img', file, file.name) // 键 数据 文件名
  }

  fetch('/api/upload', {
    body: formData,
    method: 'POST'
  })
    .then(resp => resp.json())  // 返回值必须是json格式
    .then(res => {
      img.src = res.data
    })
}
const btn = document.getElementsByTagName('button')[0]

btn.onclick = upload

服务端

使用 multer 中间件

  1. 配置文件上传处理

    • 设置 storage 磁盘存储引擎: 存储文件路径 文件名
    • 设置 limits 文件存储大小
    • 设置过滤文件 fileFilter
  2. 最好不要把 multer 设置为全局中间件,只在文件上传的 api 中配置

  3. 返回客户端存储后的文件路径,返回 json 格式是最好的

const multer = require('multer')

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, path.resolve(__dirname, '../public', 'uploads'))
  },
  filename: function (req, file, cb) {
    const ext = path.extname(file.originalname)
    const profix = Math.random().toString(36).slice(-6)
    const middle = new Date().toLocaleDateString()
    const filename = profix + middle + ext
    cb(null, file.fieldname + '-' + filename)
  }
})

function fileFilter(req,file,cb){
  const ext = path.extname(file.originalname)
  const whiteList = ['.jpg','.png']
  if(whiteList.includes(ext)){
    cb(null,true)
  }else{
    cb(new Error(`your ext ${ext} is not be supported`))
  }
}

var upload = multer({
  storage,
  limits: {
    fileSize: 500 * 1024
  },
  fileFilter,
})

router.post('/', upload.single('img'), (req, res) => {
  const url = `uploads/${req.file.filename}`
  res.send({
    code: 0,
    msg: '',
    data: url
  })
})