Лол, разве нет способа добавить больше бонусов? : D

установить.files собственностью<input type="file"> элемент кFileList например, из другого<input type="file"> элемент.files собственность илиDataTransfer.files свойство. ВидетьСделать .files настраиваемым # 2866, Что происходит между загрузкой файла в форму HTML и его отправкой?.

FileList объект имеетSymbol.iterator свойство, которое мы можем использовать, чтобы установитьFile объект, который является итеративным, однако.files .length все еще настроен на0 и прохождение<form> имеющий<input type="file"> установить где.files устанавливается с использованием вышеуказанного подхода даетFile объект, имеющий.size установлен в0.

Как установитьFile вFileList и установить.length изFileList на количество файлов, где файлы установлены вFormData() объект?

const input = document.createElement("input");

const form = document.createElement("form");

const [...data] = [
  new File(["a"], "a.txt")
, new File(["b"], "b.txt")
];

input.type = "file";

input.name = "files";

input.multiple = true;
// set `File` objects at `FileList`
input.files[Symbol.iterator] = function*() {
   for (const file of data) {
     yield file
   };
};

form.appendChild(input);

const fd = new FormData(form);

for (const file of input.files) {
  console.log(file); // `File` objects set at `data`
}

for (const [key, prop] of fd) {
  // `"files"`, single `File` object having `lastModified` property
  // set to a time greater than last `File` object within `data`
  // at Chromium 61, only `"files"` at Firefox 57
  console.log(key, prop); 
}

console.log(input.files.length); // 0

 Walle Cyril11 нояб. 2017 г., 15:34
было исправлено в FF57 см.developer.mozilla.org/en-US/Firefox/Releases/57#DOM

Ответы на вопрос(1)

Решение Вопроса
Редактировать:

по ОПв одном изих суть, на самом деле есть способ сделать это ...

DataTransfer конструктор (в настоящее время поддерживается только Blink,и FF> = 62), должен создать изменяемый FileList(в настоящее время chrome всегда возвращает новый FileList, но для нас это не имеет значения), доступный через DataTransferItemList.

Если я не ошибаюсь, это пока единственный способ сделать это, но Firefoxошибка в их реализацииКонструктор ClipboardEventгде тот же DataTransferItemList был и установлен в режимчитай пиши что позволило обойти FF <62.Я не уверен в своей интерпретации спецификаций, но я считаю, что она не должна быть доступна в обычном режиме).

Итак, путьguest271314 найдено установить произвольные файлы в FileList следующим образом:

const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
  new DataTransfer(); // specs compliant (as of March 2018 only Chrome)
dT.items.add(new File(['foo'], 'programmatically_created.txt'));
inp.files = dT.files;
<input type="file" id="inp">

Это открытие привело к этомуновое предложение сделать объекты FileList изменяемыми по умолчанию, так как больше нет смысла не делать этого.

Предыдущий (устаревший) ответ

Ты не можешь Объекты FileList не могут быть изменены скриптами *.

Вы можете только обменять FileList входных данных с другим FileList, но вы не можете изменить его *.
(* За исключением опорожнения сinput.value = null).

И вы не можете создать FileList с нуля, толькоОбмен данными объекты, которые тоже не могут быть созданы, иinput[type=file] будет создавать такие объекты.

Чтобы показать вам, что даже при настройкеinput[type=file] FileList для другого входа, новый FileList не создается:

var off = inp.cloneNode(); // an offscreen input

inp.onchange = e => {
  console.log('is same before', inp.files === off.files);
  off.files = inp.files; // now 'off' does have the same FileList as 'inp'
  console.log('is same after', inp.files === off.files);
  console.log('offscreen input FileList', off.files);
  console.log('resetting the offscreen input');
  off.value = null;
  console.log('offscreen input FileList', off.files);         
  console.log('inscreen input FileList', inp.files);
}
<input type="file" id="inp">

О, и я почти забыл часть FormData, которую я действительно не понял, чтобы сказать правду ...

Так что, если я понял, все, что вам нужно, это простоFormData.append():

var fd = new FormData();

fd.append("files[]", new Blob(['a']), 'a.txt');
fd.append("files[]", new Blob(['b']), 'b.txt');

for(let pair of fd.entries()) {
   console.log(pair[0], pair[1]); 
}

 Samuel Liew♦13 февр. 2018 г., 02:19
Не лучше ли просто отредактировать предыдущий ответ (на который все еще можно ссылаться в истории изменений), чтобы ответ был более кратким?
 Kaiido13 февр. 2018 г., 02:28
@SamuelLiew новая часть ещев основном взломать, Новые спецификации (на сегодняшний день реализованные только в Blink) позволяют это, но на самом деле это не дизайн, это скорее совпадение. Откат FF - это злоупотребление незначительной ошибкой в ​​их реализации. Так что пока это интересный хак, который, вероятно,привести к реальному APIВ настоящее время я верю, что вторая часть этого ответа все еще необходима, более того, он все еще будет действителен, даже с конструктором FileList: вы не сможете изменять FileList, только создавать новые.
 Kaiido18 мар. 2018 г., 04:06
@ mb21 Я недавно не проверял в Edge, но, насколько мне известно, только Chrome начал реализацию конструктора DataTransfer, а эксплойт FF работает только на FF. Кстати, отчет об ошибке, на который вы ссылались, на самом деле не ссылается на ошибку, о которой я говорю (я ее открыл, поэтому добавлю ссылку на нее в редактировании), хотя приятно видеть, что они работают над Это.
 inf3rno15 авг. 2018 г., 09:07
Лол, разве нет способа добавить больше бонусов? : D
 mb2117 мар. 2018 г., 16:35
@Kaiido К сожалению, мы до сих пор не можем создать новыйDataTransfer в Safari (и, возможно, IE / Edge), правильно?

Ваш ответ на вопрос