[英]How to send a file in array of object to express server?
我有一個對象數組,每個對象都包含一些字符串類型的屬性和一個文件。
這是我的數組的樣子:
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 Server。 在那里我會將信息保存到 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 捕獲文件
您不能在 JSON 中包含文件。 文件不可 JSON 序列化。 理想情況下,您應該有一個單獨的端點來接受您的文件,使用content-type: multipart/form-data
發送它們,接收存儲在服務器上的該文件的唯一 ID,然后使用 ID 而不是文件發送您的 JSON。
作為替代方案,您可以將您的文件 Base64 編碼為一個字符串,在您的請求中插入這個字符串,然后在接收端將其解碼
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); });
我使用 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')
})
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.