Como definir o valor de input do arquivo ao descartar o arquivo na página?

Eu estou tentando fazer um controle onde você pode selecionar um arquivo para enviar no formulário e soltar um arquivo para ele fazer a mesma coisa. Eu tenho algo como isso, onde também mostrará uma prévia do arquivo se for uma imagem:

 

Aqui está um violino com o MCVE .

O usuário descarta o arquivo no preview-image-container . O arquivo não é enviado com o AJAX, o usuário precisa enviar o formulário que contém mais dados.

Por motivos de segurança, não podemos alterar o valor do arquivo de input com JavaScript. No entanto, eu sei que o arquivo de input padrão suporta droppable e há um monte de sites que nos permitem selecionar arquivos, soltando-os no formulário, então meu palpite é que há uma maneira de fazê-lo.

Como você pode ver no MCVE, estou interessado apenas em usar jQuery ou JavaScript puro sem bibliotecas adicionais.

Embora o dropzone.js possa ser usado, ele não se encheckbox nos meus requisitos e exigiria uma quantidade considerável de tempo para personalizar sua aparência. Além disso, o dropzone.js possui certos requisitos de configuração que não podem ser atendidos no meu aplicativo ASP.NET.


Há uma pergunta semelhante, mas não tem uma resposta adequada:
Como definir o object de arquivo no arquivo de input no formulário em HTML?

Também não é semelhante para arrastar soltar arquivo de input de imagens e pré-visualização antes do upload, porque eu já consegui arrastar e soltar e visualizar a ação. Minha pergunta é específica para o problema de ter uma input de arquivo vazia ao descartar o arquivo em um contêiner pai.

Aviso de isenção: correto em dezembro de 2017 e apenas para navegadores modernos.


TL; DR: Sim, agora você pode!

* se você tiver um object dataTransfer ou FileList

Anteriormente , alterar programaticamente o campo de input[type=file] foi desativado devido a vulnerabilidades de segurança herdadas, que são corrigidas em navegadores modernos.

O último dos principais navegadores (Firefox), recentemente nos permitiu definir os arquivos para o campo de arquivo de input. De acordo com o teste W3C , parece que você já pode fazer isso no Google Chrome!

Captura de canvas e texto relevantes citados do MDN:

insira a descrição da imagem aqui

Você pode definir e obter o valor de HTMLInputElement.files em todos os navegadores modernos.
Compatibilidade de origem e navegador, consulte MDN

O tópico de discussão de correções de bugs do Firefox tem essa demonstração que você pode testar , e aqui está a fonte se você quiser editá-la . Para referência futura caso esse link morra, includeei também como um snippet executável abaixo:

 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>      JS Bin   

Drag and drop files into file input

Supported in WebKit and Blink. To test, drag and drop one or more files from your operating system onto this page.