【问题标题】:How to send a file in array of object to express server?如何将对象数组中的文件发送到快递服务器?
【发布时间】:2019-12-31 20:11:22
【问题描述】:

我有一个对象数组,每个对象都包含一些字符串类型的属性和一个文件。

这就是我的数组的样子:

const args = [
    {
        name: 'presentation',
        price: 9.99,
        tags: 'invest, finance, business',
        file: File,
        thumbnail: File
    },
    {
        name: 'presentation2',
        price: 20.99,
        tags: 'invest, finance, business',
        file: File,
        thumbnail: File
    }
]

const headers = {
 headers: {
   Authorization: `Bearer ${token}`
 }
};

我的目标是将整个对象数组发送到 Express 服务器。在那里我会将信息保存到 Mongo 并将文件上传到 S3。 但是目前,当我在 POST 请求中发送此文件时,我无法在服务器上获取文件流, 当我 console.log 时,甚至整个 req.body 都是一个空对象

axios.post(`${slidesRoute}/createSlides`, args, headers);

或者,我尝试将所有内容都放入 FormData。 例如:

let formData = new FormData();
    selectedFiles.forEach((selectedFile, i) => {
        formData.append(`name_${i}`, selectedFile.name);
        formData.append(`price_${i}`, selectedFile.price);
        formData.append(`tags_${i}`, selectedFile.tags);
        formData.append(`file_${i}`, selectedFile.file);
        formData.append(`thumbnail_${i}`, selectedFile.thumbnail);
    });
axios.post(`${slidesRoute}/createSlides`, formData, headers);

然后在后端。我无法使用 multer 捕获这些文件。因为表单数据中的文件名是动态生成的,就像

file_1, file_2 file_3,...

但 multer 希望传递准确的文件名 例如multer().array('file')

所以在我的第二种方法中,我无法使用 Multer 捕获文件

【问题讨论】:

  • 能否附上服务器端代码
  • 您需要添加您的服务器端处理逻辑,否则问题无法回答!

标签: javascript node.js reactjs rest express


【解决方案1】:

您不能在 JSON 中包含文件。文件不是 JSON 可序列化的。理想情况下,您应该有一个单独的端点来接受您的文件,使用content-type: multipart/form-data 发送它们,接收存储在服务器上的该文件的唯一 id,然后使用 id 而不是文件发送您的 JSON。

作为一种替代方法,您可以将您的文件 Base64 编码为一个字符串,将该字符串插入您的请求中,然后在接收端将其解码回

【讨论】:

  • 感谢您的回答。我认为将文件存储在 Base64 中会使 JSON 变得非常繁重。这将导致性能问题
  • 我尝试了另一种选择,但是当涉及到 multer 时,这变得具有挑战性。请查看更新后的问题
【解决方案2】:

FormData 键值默认为数组 在您的代码中只需更改

formData.append(`file_${i}`, selectedFile.file);

formData.append(`file`, selectedFile.file);

您应该能够使用multer().array('file') 在服务器端接收文件数组

下面的示例演示了 FormData 键值数组行为

const formData = new FormData();
formData.append('key1', 'value1');
formData.append('key1', 'value2');
formData.append('key2', 'value1');

formData.forEach(function(value, key){ 
    console.log(key, value);
    
});

【讨论】:

    【解决方案3】:

    我使用 FormData 发送一些文件 - 然后在 node.js 服务器上我使用 Formidable。

    我在下面粘贴了一些可能有帮助的部分代码 - 抱歉,这不是一个较小的示例。

    希望对你有帮助

    在浏览器端我有:

    let form_data = new FormData()
    form_data.append('upload_data', file)
    $.ajax({
      url: '/file/upload' + remote_path + '/' + filename,
      type: 'POST',
      data: form_data,
      processData: false,
      contentType: false,
      success: (res) => {
    ...
    

    在 node.js 方面(为长度道歉..)我有:

    const fs = require('fs')
    const formidable = require('formidable')
    const path = require('path')
    ...
    app.post('/file/upload/*', (req, res) => {
    let filename = req.params[0]
    let media = path.basename(filename)
    let folder = filename.substring(0, filename.length - media.length)
    let form = new formidable.IncomingForm()
    // form.encoding = 'utf-8'
    form.multiples = true
    form.uploadDir = path.join(media_folder, folder)
    form.keepExtensions = true
    form.parse(req, (err, fields, files) => {
      if (err) {
        fail(res, 'failed to upload')
      } else {
        success(res)
      }
    })
    form.on('fileBegin', (name, file) => {
      const [fileName, fileExt] = file.name.split('.')
      file.path = path.join(form.uploadDir, `${fileName}_${new Date().getTime()}.${fileExt}`)
    })
    form.on('file', (field, file) => {
      fs.rename(file.path, path.join(form.uploadDir, file.name), (err) => {
        if (!res.headersSent) { // Fix since first response is received
          fail(res, 'an error has occured with form upload' + err)
        }
      })
    })
    form.on('error', (err) => {
      fail(res, 'an error has occured with form upload' + err)
    })
    form.on('aborted', (err) => {
      fail(res, 'Upload cancelled by browser')
    })
    

    })

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-15
      • 2019-08-24
      • 2016-06-06
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 2019-05-27
      相关资源
      最近更新 更多