我在上传多张图片时遇到问题。我一直在尝试多种选择,但似乎无济于事。
这是我的PUG
form#new-shortcut.form-horizontal.elegant-color-dark(action=`/themes/new?_csrf=${csrfToken}` method='POST' enctype='multipart/form-data')
input#csrf(type='hidden' name='_csrf' value=`${csrfToken}`)
input#files.file_updload(type='file' multiple='multiple' accept='image/*' name='photosArr[]')
哪个呈现给这个
<form class="form-horizontal elegant-color-dark" id="new-shortcut" action="/themes/new?_csrf=undefined" method="POST" enctype="multipart/form-data">
<input id="csrf" type="hidden" name="_csrf" value="undefined" />
<input class="file_updload" id="files" type="file" multiple="multiple" accept="image/*" name="photosArr[]" />
</form>
这是chrome控制台在检查是否添加文件时输出。
document.querySelector('#files').files
> FileList {0: File, 1: File, length: 2}
function formidablePromise(req, opts) {
return new Promise(((resolve, reject) => {
const form = new formidable.IncomingForm(opts);
form.parse(req, (err, fields, files) => {
if (err) return reject(err);
resolve({ fields, files });
});
}));
}
router.post('/themes/new', csrfProtection, async (req, res, next) => {
console.log('reached');
const form = await formidablePromise(req);
const filePaths = [];
let base64img;
try {
const promises = [];
console.log(form.files)
Object.keys(form.files).forEach((key) => {
console.log(form.files[key].path);
const filePath = `${process.env.PC_DIR}${nanoid()}${form.files[key].name}`;
filePaths.push(filePath);
promises.push(fs.move(form.files[key].path, `${filePath}`));
});
await Promise.all(promises);
console.log(filePaths);
console.log(form.fields)
// filepath = `/Users/lucjangrzesik/Desktop/themegrams/public/img/${nanoid()}${form.files.file.name}`;
// await fs.move(form.files.file.path, filepath);
console.log('success!');
} catch (err) {
return console.error(err);
}
try {
const promises = [];
for (let index = 0; index < filePaths.length; index++) {
promises.push(bucket.upload(filePaths[index]));
}
const data = await Promise.all(promises);
console.log(data);
} catch (err) {
console.error('ERROR:', err);
}
try {
const promises = [];
for (let index = 0; index < filePaths.length; index++) {
promises.push(image2base64(filePaths[index]));
}
const data = await Promise.all(promises);
const imgurPromises = [];
for (let index = 0; index < data.length; index++) {
imgurPromises.push(imgur.uploadBase64(data[index]));
}
const images = await Promise.all(imgurPromises);
const links = [];
images.forEach((e) => {
links.push(e.data.link);
});
console.log(links)
res.redirect('/');
// await fs.remove(filepath);
} catch (error) {
console.log(error);
return res.redirect('back');
}
});
表单仅接收一个文件。
{
'photosArr[]': File {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
size: 427923,
path: 'C:\\Users\\Lucien\\AppData\\Local\\Temp\\upload_0f6dc87e49472d18c12a8d0686bb6215',
name: 'BANDEAU SOLDES CDO outlet 1800.png',
type: 'image/png',
hash: null,
lastModifiedDate: 2020-01-13T13:24:06.281Z,
_writeStream: WriteStream {
_writableState: [WritableState],
writable: false,
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
path: 'C:\\Users\\Lucien\\AppData\\Local\\Temp\\upload_0f6dc87e49472d18c12a8d0686bb6215',
fd: null,
flags: 'w',
mode: 438,
start: undefined,
autoClose: true,
pos: undefined,
bytesWritten: 427923,
closed: false
}
}
}
我正在使用node-formidable来检索表单。
当我使用ajax服务器发送表单时,将接收所有文件。这是ajax代码
const csrf = document.querySelector('#csrf').getAttribute('value');
const headers = {
'X-Requested-With': 'XMLHttpRequest',
'CSRF-Token': csrf,
};
const fileInput = document.querySelector('#file');
const imagesDiv = document.querySelector('#images>.row.d-flex.justify-content-around');
async function sendData(data) {
const output = document.getElementById('imgThumbnailPreview');
output.innerHTML = '';
const formData = new FormData();
// - formData.append('file', fileInput.files[0]);
for (const name in data) {
formData.append(name, data[name]);
}
console.log(formData);
for (let i = 0; i < fileInput.files.length; i += 1) {
const imageDiv = document.createElement('div');
imageDiv.classList.add('col-12', 'col-sm-6', 'col-md-4', 'col-lg-3', 'mt-2');
const elem = document.createElement('div');
elem.classList.add('card-loader', 'card-loader--tabs');
imageDiv.append(elem);
imagesDiv.append(imageDiv);
}
fileInput.value = '';
const response = await fetch('http://localhost:3000/upload', {
method: 'POST',
headers,
body: formData,
});
const imagesArr = document.querySelectorAll('.card-loader.card-loader--tabs');
const imagesUrl = await response.json();
for (let index = 0; index < imagesUrl.links.length; index++) {
imagesArr[index].parentNode.innerHTML = `<img class='img-fluid' src='${imagesUrl.links[index]}'/><input name='images[${index}]' type="hidden" value="${imagesUrl.links[index]}">`
}
}
因此问题不在于表格,而在于强大的配置;我只需要将form.multiples = true;
添加到formidablePromise函数中即可。
function formidablePromise(req, opts) {
return new Promise(((resolve, reject) => {
const form = new formidable.IncomingForm(opts);
form.multiples = true;
form.parse(req, (err, fields, files) => {
if (err) return reject(err);
resolve({ fields, files });
});
}));
}