Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/478.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将对象数组中的文件发送到express server?_Javascript_Node.js_Reactjs_Rest_Express - Fatal编程技术网

Javascript 如何将对象数组中的文件发送到express server?

Javascript 如何将对象数组中的文件发送到express server?,javascript,node.js,reactjs,rest,express,Javascript,Node.js,Reactjs,Rest,Express,我有一个对象数组,每个对象包含一些字符串类型的属性和一个文件 这就是我的阵列的外观: const args = [ { name: 'presentation', price: 9.99, tags: 'invest, finance, business', file: File, thumbnail: File }, { name: 'presentation2',

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

这就是我的阵列的外观:

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请求中发送此文件时,无法在服务器上获取文件流, 即使是整个
req.body
在我console.log时也是一个空对象

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捕获文件,因为您不能在JSON中包含文件。文件不可JSON序列化。理想情况下,您应该有一个单独的端点来接受您的文件,使用
内容类型发送它们:multipart/form data
,接收存储在服务器上的该文件的唯一id,然后使用id而不是文件发送JSON


作为一种chaper替代方法,您可以将文件Base64编码为字符串,在请求中插入该字符串,然后在接收端将其解码回来。默认情况下,数据键值是数组 在代码中只需更改

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

您应该能够使用
multer().array('file')

下面的示例演示FormData键值数组行为
const formData=new formData();
formData.append('key1','value1');
formData.append('key1','value2');
formData.append('key2','value1');
forEach(函数(值,键){
console.log(键、值);

});我使用FormData发送大量文件,然后在node.js服务器上使用FormData

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

希望能有帮助

在浏览器端,我有:

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端(抱歉长度…),我有:


})

谢谢您的回答。我认为在Base64中存储文件会使JSON非常繁重。这将导致性能问题我尝试了另一种选择,但对于multer来说,这将是一个挑战。请查看更新的问题。请附上服务器端代码。您需要添加服务器端处理逻辑,否则问题无法回答!
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) => {
...
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')
})