表单仅发送一个文件/图像

问题描述 投票:0回答:1

我在上传多张图片时遇到问题。我一直在尝试多种选择,但似乎无济于事。

前端代码


这是我的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');
  }
});

console.log(form.files)返回

表单仅接收一个文件。

{
  '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服务器发送表单时,将接收所有文件。这是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]}">`
  }
}
javascript node.js forms express formidable
1个回答
0
投票

因此问题不在于表格,而在于强大的配置;我只需要将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 });
    });
  }));
}
© www.soinside.com 2019 - 2024. All rights reserved.