Node读取前端上传文件、图片通过FormData转换,搭配"multipart/form-data"上传图片,Node读取参数通过管道流储存图片

4,800 阅读1分钟

问题

是因为再使用Node,来接受前端传来的form-data参数,通过req.body获取不到,解析为{}空对象,后来发现原来是AJAX携带文件上传,前端采用的是multipart/form-data

1.HTML

 <form class="editForm">
    <div class="form-group">
      <label for="email">头像</label>
      <input type="file" name="pic" id="headImg" accept="image/*">
    </div>
    <div class="form-group">
      <label for="user">账号</label>
      <input type="username" id="username" name="username" value="" class="form-control" id="user"
        placeholder="请输入新的账号">
    </div>
    <div class="form-group">
      <label for="password">密码</label>
      <input type="password" id="password" name="password" value="" class="form-control" id="password"
        placeholder="请输入新的账号">
    </div>
  </form>

2.JS

 function editSelf(res) {
    const headImg = document.getElementById('headImg').files[0]
    const username = document.getElementById('username').value
    const password = document.getElementById('password').value
    const data = new FormData()
    data.append('src', headImg)
    data.append('username', username)
    data.append('password', password)
    $.ajax({
      url: "/editSelf",
      type: 'POST',
      cache: false,
      data,//这里就是通过formData转换后的数据
      timeout: 5000,
      //必须false才会避开jQuery对 formdata 的默认处理 
      processData: false,
      //必须false才会自动加上正确的Content-Type 
      contentType: false,
      xhrFields: {
        withCredentials: true
      },
      success: function (data) {
        ....
      }
    })
  }

3.Node

** node下载插件 npm install connect-multiparty用来解析multiparty**

const multipart = require('connect-multiparty');
const multipartMiddleware = multipart();

//在路由editSelf里
//编辑个人资料接口
router.post('/editSelf', multipartMiddleware,(req, res, next) => {
  const file=req.files //这个就是前端传来的文件
  const data=req.body //这个就是username和password
  util.editSelf(req.files, (response) => {
    next(response)
  })
})

4.结果

浏览器network展示的接口信息 Node里connect-multiparty插件把数据切割成2份,文件数据放到req.files,其他数据展示到req.body 最后利用node里的fs模块,fs.createReadStream()读取文件、fs.createWriteStream()写入文件

exports.editSelf = (data, callback) => {
  const img = fs.createReadStream(data.src.path)
  const nono = fs.createWriteStream('./assets/asas.jpg')
  img.pipe(nono)//这一步就是管道流传输
  //读取文件发生错误事件
  img.on('error', (err) => {
    console.log('发生异常:', err);
  });
  //已打开要读取的文件事件
  img.on('open', (fd) => {
    console.log('文件已打开:', fd);
  });
  //文件已经就位,可用于读取事件
  img.on('ready', () => {
    console.log('文件已准备好..');
  });

  //文件读取中事件·····
  img.on('data', (chunk) => {
    console.log('读取文件数据:', chunk);
  });

  //文件读取完成事件
  img.on('end', () => {
    console.log('读取已完成..');
  });

  //文件已关闭事件
  img.on('close', () => {
    console.log('文件已关闭!');
  });
}

很少写文章,不知道能不能表达清楚,虚心学习,虚心接受指正和批评,谢谢观看,(#^.^#)嘻嘻