gue*_*314 29 javascript form-data filelist fileapi
可以将元素的.files属性设置为例如来自不同的元素属性或属性.请参阅Make .files settable#2866,将文件上传到HTML表单并提交之间会发生什么?.<input type="file">FileList<input type="file">.filesDataTransfer.files
FileList对象有一个Symbol.iterator属性,我们可以使用它来设置一个File可迭代的对象,但是.files .length仍然设置为0并传递一个<form>有<input type="file">用于.files使用上述方法设置的集合,产生一个设置为的File对象..size0
如何设置Fileat FileList和set设置.length的FileList文件数,文件在FormData()object 设置的位置?
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); // 0Run Code Online (Sandbox Code Playgroud)
Kai*_*ido 44
作为成熟的OP,在一个其要点,实际上是一个办法做到这一点?
该数据传递构造函数(目前只有闪烁的支持,以及FF> = 62),应该创建一个可变的文件清单(目前铬总是返回一个新的文件清单,但它并没有真正的问题对我们来说),通过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;Run Code Online (Sandbox Code Playgroud)
<input type="file" id="inp">Run Code Online (Sandbox Code Playgroud)
这个发现导致这个新的Proposal默认情况下使FileList对象可变,因为没有必要再做它.
你不能.脚本*不能修改FileList对象.
您只能将输入的FileList交换到另一个FileList,但不能修改它*.
(*除了清空input.value = null).
而且你不能从头开始创建FileList,也不能创建无法创建的DataTransfer对象,并且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);
}Run Code Online (Sandbox Code Playgroud)
<input type="file" id="inp">Run Code Online (Sandbox Code Playgroud)
哦,我差点忘了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]);
}Run Code Online (Sandbox Code Playgroud)