Я работаю над перетаскиванием vanilla JavaScript uploader, подключенным к полю multiple
file input
. Учебники по SO имеются в большом количестве, но они не касаются обработки ошибок и необходимости удалять файл из FileList
перед загрузкой, если человек загрузил файл, который не прошел пользовательскую проверку. Бизнес-логика c заключается в том, что у вас есть перетаскивание, которое принимает только файлы PDF, а пользователь добавляет любой тип файла, кроме PDF. Я не могу просто очистить ввод и сказать пользователю попробовать еще раз - я могу поднять UX больше, чем это.
Важно отметить, что я не хочу использовать какие-либо AJAX logi c загрузить файл base64 на сервер и вернуть его до публикации формы - потому что у меня есть пользовательские PHP сохраняемые логи c, подключенные к сторонней платформе. Мой код ожидает данные $_FILES
, прикрепленные к имени ввода. Я не хочу переписывать весь бэкэнд PHP, сохраняя логи c на месте, просто чтобы обойти эту глупую FileList
только для чтения логи c.
Так что на данный момент я знаю FileList
только для чтения по соображениям безопасности, поэтому, к сожалению, я не могу просто удалить файлы, которые необходимо было удалить из-за того, что проверка не прошла из поля input
. Поэтому я должен перебрать поле input
, а затем выполнить мою проверку.
На данный момент у меня все в порядке с получением данных в отброшенном вводе, чтением и выполнением проверки примерно так:
let goodFiles = [];
/* run through the files */
for (let i =0; i < e.dataTransfer.files.length; i++) {
if (e.dataTransfer.files[i].type === 'application/pdf') {
//e.dataTransfer.files[i] is the current file and it is good
goodFiles.push(e.dataTransfer.files[i]);
} else {
//we will not need this file, so we want to remove it
}
}
Но этот goodFiles
является просто массивом, и когда я пытаюсь добавить это к новому multiple
file
input
, он терпит неудачу, поскольку не является истинным FileList
:
let i = document.createElement('input');
i.setAttribute('type','file');
i.setAttribute('name','goodFiles[]')
i.files = goodFiles;
Вышесказанное не работает, так как оно не соответствует действительности FileList
.
Итак, я попытался сделать следующее:
let dt = new DataTransfer();
/* run through the files */
for (let i =0; i < e.dataTransfer.files.length; i++) {
if (e.dataTransfer.files[i].type === 'application/pdf') {
//e.dataTransfer.files[i] is the current file and it is good
dt.items.add(new File([],e.dataTransfer.files[i].name))
} else {
//we will not need this file, so we want to remove it
}
}
let i = document.createElement('input');
i.setAttribute('type','file');
i.setAttribute('name','files[]')
i.files = dt.files;
Но это не так При передаче в PHP истинный файл выводится как application/octect-stream
. Я думаю, что я могу создать новый файл только при вызове new File()
и не передавать FileList
объект в new File()
? Я не хочу создавать новый файл - у меня есть FileList
, а теперь массив утвержденных, я просто хочу прикрепить его к полю multiple
file
input
.
Так что я в растерянности и ищу кого-нибудь, кто бы помог мне пересечь финишную линию sh. Мне нужно перебрать файлы multiple
, прикрепленные к входу, запустить проверку, а затем передать новый FileList
недавно созданному элементу input
для передачи в PHP для обработки сохранения при отправке формы всех поля ввода сразу.