Как установить значение входного файла при выпадающем файле на странице?

Я пытаюсь сделать элемент управления, где вы можете выбрать файл для отправки в форме и поместить в него файл, чтобы сделать то же самое. У меня есть что-то вроде этого, где он также покажет предварительный просмотр файла, если это изображение:

<div class="preview-image-container" style="cursor: default;">
    <input type="file" name="File" id="File" class="form-control" accept="image/*" style="display:none;">
    <div class="preview-image-dummy"></div><img class="preview-image-url">
    <div class="preview-image-instruction" style="background-color: inherit; cursor: default;"><i class="fa fa-4x fa-cloud-upload" aria-hidden="true"></i>
        <div class="preview-image-btn-browse btn btn-primary">Select file</div>
        <p>or drop it here.</p>
    </div>
</div>

Пользователь выгружает файл в контейнер предварительного просмотра. Файл не отправляется с AJAX, пользователю необходимо отправить форму, содержащую больше данных.

Из соображений безопасности нам не разрешено изменять значение входного файла с помощью JavaScript. Тем не менее, я знаю, что поддержка входных файлов по умолчанию недоступна, и есть куча веб-сайтов, которые позволяют нам выбирать файлы, отбрасывая их в форме, поэтому я предполагаю, что есть способ сделать это.

Аналогичный вопрос, но не имеет правильного ответа:
Как установить файл файл во входной файл в форме в формате HTML?

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


Здесь скрипка с MCVE. Как вы можете видеть, меня интересует только использование jQuery или чистого JavaScript без дополнительных библиотек.

Хотя dropzone.js можно использовать, оно не соответствует моим требованиям, и для его просмотра потребуется много времени. Кроме того, у dropzone.js есть определенные требования к конфигурации, которые не могут быть выполнены в моем приложении ASP.NET.

Ответ 1

Отказ от ответственности: Исправьте с декабря 2017 года и только для современных браузеров.


TL; DR: Да, теперь вы можете!

* если у вас есть объект dataTransfer или FileList

Ранее, программное изменение файла input[type=file] было отключено из-за устаревших уязвимостей безопасности, которые исправлены в современных браузерах.

Последний из основных браузеров (Firefox) недавно позволил нам установить файлы для поля входного файла. Согласно тестирование W3C, похоже, что вы уже можете сделать это в Google Chrome!

Соответствующий скриншот и текст, цитируемый из MDN:

enter image description here

Вы можете установить, а также получить значение HTMLInputElement.files во всех современных браузерах.
Совместимость источников и браузеров, см. MDN

В Firefox bugfix обсуждение в этой демо вы можете test, и здесь источник, если вы хотите отредактировать его. Для дальнейшего использования в случае, если эта ссылка замирает, я также включу ее в качестве исполняемого фрагмента ниже:

let target = document.documentElement;
let body = document.body;
let fileInput = document.querySelector('input');

target.addEventListener('dragover', (e) => {
  e.preventDefault();
  body.classList.add('dragging');
});

target.addEventListener('dragleave', () => {
  body.classList.remove('dragging');
});

target.addEventListener('drop', (e) => {
  e.preventDefault();
  body.classList.remove('dragging');
  
  fileInput.files = e.dataTransfer.files;
});
body {
  font-family: Roboto, sans-serif;
}

body.dragging::before {
  content: "Drop the file(s) anywhere on this page";
  position: fixed;
  left: 0; width: 100%;
  top: 0; height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.5em;
  background-color: rgba(255, 255, 0, .3);
  pointer-events: none;
}

button, input {
  font-family: inherit;
}

a {
  color: blue;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
      <link href="#" onclick="location.href='https://fonts.googleapis.com/css?family=Roboto:400,400i,700'; return false;" rel="stylesheet"> 

  <title>JS Bin</title>
</head>
<body>
  
  <h1>Drag and drop files into file input</h1>
  
  <p><small>Supported in <a href="#" onclick="location.href='https://github.com/whatwg/html/issues/2861'; return false;">WebKit and Blink</a>. To test, drag and drop one or more files from your operating system onto this page.</small></p>
  
  <p>
    <input type="file">
  </p>

</body>
</html>