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')
})