How do I programmatically insert files into input?

  • 0
    For a long time I thought that this was basically impossible, but experimenting with prototypes of objects, I suddenly realized that the task was not so impossible. As a result, having killed the whole day for tests, I found a solution) At the request of one person, I post working versions of the code for inserting arbitrary files into the file selection fields.

    Where can it come in handy? Mostly for JavaScript bots, when you need to upload files somewhere in the form and there is absolutely no way to unravel the heavily obfuscated code, and without this you cannot transfer the files directly.
    JavaScript Elliot McLean, Mar 19, 2020

  • 1 Answers
  • 0
    I came across two solutions for this problem.



    The first method allows you to insert an arbitrary Blob into the field & lt; input type = "file" & gt; and for the handlers on the target site everything will look like in the field files are actually present, although this of course will not be so.



    So the function to insert is:

    // Пример функции для вставки Blob в поле input:

    function pasteBlobToInput(blob, input) {

    // Конвертируем Blob в File:
    var file = new File([blob], blob.name);

    // Создаем коллекцию файлов для последующий вставки:
    var file_list = {0: file, length: 1, '__proto__': input['files']['__proto__']};

    // Сохраняем прототип поля:
    var proto = input['__proto__'];

    // Подменяем прототип для разблокировки св-ства files на запись:
    input['__proto__'] = document.createElement('div')['__proto__'];

    // Записываем коллекцию файлов:
    input['files'] = file_list;

    // Возвращаем прототип на место:
    input['__proto__'] = proto;

    // Выводим уведомление:
    console.log('Коллекция успешно вставлена:');
    console.dir(file_list);

    // Заставляем сработать обработчики на поле выбра файлов:
    input.dispatchEvent(new InputEvent('change', { bubbles: true }));

    }


    The first parameter of the function is Blob , and the second is the input element where you want to insert it. Note that Blob must have a name in the name property. If you have Blob without a name, then add it. Unfortunately, the collection of files created in the way above is incomplete, but even this incomplete collection is enough to fool the handlers. I wrote this solution for a WhatsApp bot and everything really works for me there)



    The second option allows you to get complete collections of files and then insert them and use them anywhere. First, we need to include the localforage library:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.9.0/localforage.js"></script>


    Next, we can select files for collection and save them in the browser memory:

    var input = document.createElement('input');
    input.setAttribute('type', 'file');
    input.setAttribute('multiple', 'multiple');
    input.addEventListener('change', async function() {
    var files = await localforage.setItem('files', this.files);
    console.log('Коллекция файлов успешно сохранена:');
    console.dir(files);
    });
    input.click();


    We can later use the saved collection even after reloading the page or closing / opening the browser. To retrieve a saved collection, just run:

    var files = await localforage.getItem('files');
    console.log('Коллекция файлов успешно извлечена:');
    console.dir(files);


    This collection is complete and we can easily attach it to any field:

    var files = await localforage.getItem('files');
    document.querySelector('input[type="file"]').files = files;


    In this case, the files in the field will look exactly the same as if they were selected from a computer, no difference.
    Anonymous

Your Answer
To place the code, please use CodePen or similar tool. Thanks you!