@zkrvndm
Боты, парсеры, расширения

Как программно вставить файлы в input?

Я долгое время думал, что это в принципе невозможно, но экспериментируя с прототипами объектов я внезапно осознал, что задача и не такая уж невозможная. В итоге, убив на тесты целый день нашел решение) По просьбе одного человека, выкладываю рабочие варианты кода для вставки произвольных файлов в поля выбора файлов.

Где это может пригодится? В основном для JavaScript-ботов, когда требуется подгрузить файлы куда-нибудь форму и при это совершенно нет никакой возможности распутать сильно обфусцированный код, а без этого файлы напрямую не передать.
  • Вопрос задан
  • 125 просмотров
Решения вопроса 1
@zkrvndm Автор вопроса
Боты, парсеры, расширения
Я нащупал два решения для этой проблемы.

Первый способ позволяет вставить произвольный Blob в поле <input type="file"> и для обработчиков на целевом сайте все будет выглядеть, будто в поле реально присутствуют файлы, хотя это конечно будет не так.

Итак, функция для вставки:
// Пример функции для вставки 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 }));
	
}

Первым параметром функции передаем Blob, а вторым элемент input куда нужно его вставить. Обратите внимание, что Blob должен иметь имя в свойстве name. Если у вас Blob без названия, то добавьте его. К сожалению, коллекция файлов способом выше создается неполноценная, но даже этой неполноценной коллекции достаточно чтобы обмануть обработчики. Я писал это решение для WhatsApp-бота и там у меня реально все работает)

Второй вариант позволяет получать полноценные коллекции файлов и далее их вставлять и использовать их где угодно. Для начала нам нужно подключить библиотеку localforage:
<script src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.9.0/localforage.js"></script>

Далее, мы можем выбрать файлы для коллекции и сохранить их в памяти браузера:
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();

Сохраненную коллекцию мы позднее сможем использовать даже после перезагрузки страницы или закрытия / открытия браузера. Для извлечения сохраненной коллекции достаточно выполнить:
var files = await localforage.getItem('files');
console.log('Коллекция файлов успешно извлечена:');
console.dir(files);

Эта коллекция полноценная и мы легко можем ее прицепить в любое поле:
var files = await localforage.getItem('files');
document.querySelector('input[type="file"]').files = files;

При этом файлы в поле будут выглядеть точно так же, будто выбраны с компа, никаких отличий.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
PentiumMmx
@PentiumMmx
Мы живем не один раз, а каждый день!!
Не подскажите как в Blob загрузить csv? Через FileReader ?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы