Не работает многофайловый ввод html

У меня есть следующий код для ввода нескольких файлов

<form action="" enctype = "multipart/form-data" method="post" name="login">

<input type = "file" name = "photo[]" id = "files" multiple onchange =  "handleFileSelect(this.files)"/><br/>
<div id="selectedFiles"></div>
<input type="submit" value="Sign In">
</form>

Эквивалентная функция javascript

selDiv = document.querySelector("#selectedFiles");
function handleFileSelect(e) {
    if(!this.files) return;

    selDiv.innerHTML = "";

    var files = e;
    for(var i=0; i<files.length; i++) {
        var f = files[i];
        selDiv.innerHTML += f.name + "<br/>";

    }

}

Что я получаю при загрузке второго файла. FileList перезаписывается, и вместо двух файлов, второй файл присутствует в FileList. Здесь FileList передается this.files.

Также при передаче на сервер передается только второе изображение. Я погуглил насквозь, но не смог найти ответ. Буду признателен, если кто-нибудь сможет помочь.

2 ответа

Решение

Я столкнулся с той же проблемой. Спасибо за вопрос и ответ. Мне удалось добавить несколько файлов, добавив их в файл типа ввода DOM и делегировав щелчок на отдельный элемент:

<form method="POST" enctype="multipart/form-data" action="/echo/html">
  <button class="add">
    Add File
  </button>
  <ul class="list">
  </ul>
  <button>
      Send Form
  </button>
</form>

С помощью JavaScript:

$('form button.add').click(function(e) {
    e.preventDefault();
    var nb_attachments = $('form input').length;
    var $input = $('<input type="file" name=attachment-' + nb_attachments + '>');
    $input.on('change', function(evt) {
        var f = evt.target.files[0];
        $('form').append($(this));
        $('ul.list').append('<li class="item">'+f.name+'('+f.size+')</li>');
    });
    $input.hide();
    $input.trigger('click');
});

Он работает с Edge, Chrome 50 и firefox 45, но я не знаю совместимости со старыми версиями или другими браузерами.

Вижу эту скрипку.

На самом деле это то, как ввод файла HTML с multiple Атрибут работает. Пользователь должен выбрать все файлы, которые он хочет загрузить, используя Shift или Control.

Чтобы позволить пользователям вашего сайта использовать элемент ввода файла HTML несколько раз и сохранить все предыдущие варианты выбора, вам нужно будет записывать полученные данные файла base64 при каждом использовании этого элемента в скрытые элементы формы.

<form action="process.php" method="post" name="uploadform" enctype="multipart/form-data">
  // other form elements if needed
  <input type="submit">
</form>

<!-- outside the form, you don't want to upload this one -->
<input type="file" id="upfiles" name="upfiles">

<script>

  document.getElementById('upfiles').addEventListener('change', handle_files, false);

  function handle_files(evt) {

    var ff = document.forms['uploadform'];
    var files  = evt.target.files;

    for ( var i = 0, file; file = files[i]; i++ ) {

      var reader = new FileReader();

      reader.onload = (function(file) {
        return function (ufile) {
          var upp = document.createElement('input');
          upp['type'] = 'hidden';
          upp['name'] = +new Date + '_upfile_' + file.name.replace(/(\[|\]|&|~|!|\(|\)|#|\|\/)/ig, '');
          upp.value = ufile.target.result;
          ff.appendChild(upp);
        }
      }(file));

      reader.readAsDataURL(file);
    }
  }
</script>

Затем вам нужно написать скрипт для запуска на сервере для обработки скрытых полей base64. Если вы используете PHP, вы можете:

<?php

$path = 'path/to/file/directory/';
// this is either:
//    - the absolute path, which is from server root
//      to the files directory, or
//    - the relative path, which is from the directory 
//      the PHP script is in to the files directory

foreach ( $_POST as $key => $value ) { // loop over posted form vars
  if ( strpos($key, '_upfile_') ) {    // find the file upload vars
    $value = str_replace(' ', '+', $value); // url encode
    file_put_contents($path.$key, base64_decode($value));
    // convert data to file in files directory with upload name ($key)
  }
}

?>
Другие вопросы по тегам