@zkrvndm
Софт для автоматизации

Существуют ли способы удалять файлы выборочно из input multiple?

Предположим имеется поле для вставки файлов с атрибутом multiple, т. е. в него можно вставить сразу много файлов. Могу ли я после выбора файлов посредством JavaScript удалить определенные из них?

Говоря точнее, существуют ли способы удалять элементы из коллекции FileList? Какие-нибудь обходные пути с использованием расширений Chrome?

Возможно существуют способы блобы вставлять в поля как файлы? Блобы то я могу редактировать как хочу.

document.querySelector('input[type="file"]').files; // Коллекция файлов
  • Вопрос задан
  • 370 просмотров
Решения вопроса 3
Stalker_RED
@Stalker_RED
Скриптам запрещено редактировать FileList (доступ readonly).
Можно прочитать содержимое, можно полностью очистить, но ни добавить ни частично очистить нельзя.

Зато можно прочитать, убрать лишнее, нужные поля собрать в FormData и отправить это ajax-ом.
https://developer.mozilla.org/ru/docs/Web/API/Form...
Ответ написан
@Soul1Eat
Судя по всему цель ботоводство, а значит почему бы уже не перейти на Puppeteer? И возможностей больше и танцов с бубном меньше, да и судя по первому попавшемуся issue
// Client validation button
const validateClient = await page.$(`section:nth-child(6) > div.span3 > div:nth-child(1) > div > div > input[type="file"]`);
await validateClient.uploadFile('/path/to/file.csv'):

Даже это реализовать просто
Ответ написан
@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;

При этом файлы в поле будут выглядеть точно так же, будто выбраны с компа, никаких отличий.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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