Javascript 如何在FileList对象上设置文件对象和长度属性,其中文件也反映在FormData对象上?

Javascript 如何在FileList对象上设置文件对象和长度属性,其中文件也反映在FormData对象上?,javascript,form-data,fileapi,filelist,Javascript,Form Data,Fileapi,Filelist,可以将元素的.files属性设置为文件列表,例如从不同的元素.files属性或数据传输.files属性。见 文件列表对象有一个符号。迭代器属性,我们可以使用该属性设置可编辑的文件对象,但是,.files.length仍然设置为0,并在使用上述方法设置.files的位置传递一个设置为的文件对象,该对象的.size设置为0 如何将文件设置在文件列表处,并将文件列表的长度设置为设置的文件数,其中文件设置在FormData()对象处 const input=document.createElement

可以将
元素的
.files
属性设置为
文件列表
,例如从不同的
元素
.files
属性或
数据传输.files
属性。见

文件列表
对象有一个
符号。迭代器
属性,我们可以使用该属性设置可编辑的
文件
对象,但是,
.files
.length
仍然设置为
0
,并在使用上述方法设置
.files
的位置传递一个
设置为
文件
对象,该对象的
.size
设置为
0

如何将
文件
设置在
文件列表
处,并将
文件列表
长度
设置为设置的文件数,其中文件设置在
FormData()
对象处

const input=document.createElement(“输入”);
const form=document.createElement(“表单”);
常数[…数据]=[
新文件([“a”],“a.txt”)
,新文件([“b”],“b.txt”)
];
input.type=“文件”;
input.name=“文件”;
input.multiple=true;
//在“文件列表”中设置“文件”对象`
input.files[Symbol.iterator]=函数*(){
for(数据的常量文件){
屈服文件
};
};
表单。追加子项(输入);
const fd=新表单数据(表单);
for(输入文件的常量文件){
console.log(文件);//`file`对象设置在`data`
}
用于(fd的常量[键,道具]){
//`files`,具有`lastModified`属性的单个`File`对象
//设置为大于“数据”中最后一个“文件”对象的时间`
//在Chromium 61上,Firefox 57上只有“文件”
控制台日志(键、道具);
}
console.log(input.files.length);//0
编辑: 正如OP所证明的那样,实际上有一种方法可以做到这一点

(目前只支持Blink,)应该创建一个可变的文件列表(chrome当前总是返回一个新的文件列表,但这对我们来说并不重要),可以通过DataTransferItemList访问

如果我没有弄错的话,这是目前唯一一种符合规范的方法,但是Firefox在其实现中有一个bug,其中相同的DataTransferItemList被设置为读/写模式,允许FF<62的解决方法。我不确定我对规范的解释,但我认为它不应该正常访问)

因此,guest271314在文件列表上设置任意文件的方法如下:

const dT=new ClipboardEvent(“”).clipboardData | |//Firefox<62解决方案https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
新建数据传输();//符合规格(截至2018年3月,仅限铬合金)
add(新文件(['foo'],'programmetically_created.txt');
inp.files=dT.files
编辑: 正如OP所证明的那样,实际上有一种方法可以做到这一点

(目前只支持Blink,)应该创建一个可变的文件列表(chrome当前总是返回一个新的文件列表,但这对我们来说并不重要),可以通过DataTransferItemList访问

如果我没有弄错的话,这是目前唯一一种符合规范的方法,但是Firefox在其实现中有一个bug,其中相同的DataTransferItemList被设置为读/写模式,允许FF<62的解决方法。我不确定我对规范的解释,但我认为它不应该正常访问)

因此,guest271314在文件列表上设置任意文件的方法如下:

const dT=new ClipboardEvent(“”).clipboardData | |//Firefox<62解决方案https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
新建数据传输();//符合规格(截至2018年3月,仅限铬合金)
add(新文件(['foo'],'programmetically_created.txt');
inp.files=dT.files

已在FF57中修复请参见已在FF57中修复请参见@SamuelLiew新部件仍然主要是黑客攻击。新的规范(目前只在Blink中实现)允许这样做,但这并不是设计上的,更像是巧合。FF回退是在其实现中滥用了一个小错误。因此,虽然这是一个有趣的黑客攻击,可能暂时还需要这个答案的第二部分,而且,即使使用文件列表构造函数,它仍然是有效的:您将无法修改文件列表,只能创建新的。@kaido不幸的是,我们仍然无法在Safari(可能还有IE/Edge)中创建新的
DataTransfer
,对吗?@mb21我最近没有在Edge中检查,但是的,据我所知,只有Chrome已经开始实施DataTransfer构造函数,FF漏洞仅在FF上有效。顺便说一句,你链接到的bug报告并没有真正提到我所说的bug(我打开了一个,所以我会在编辑中添加一个链接),尽管很高兴看到他们正在处理它。我们仍然无法在Safari中调用
DataTransfer
构造函数,IE/Edge数据传输构造器现在在基于铬的Edge中工作。@SamuelLiew新的部分仍然主要是一个黑客。新的规范(目前只在Blink中实现)允许这样做,但这并不是设计上的,更像是巧合。FF回退是在其实现中滥用了一个小错误。因此,虽然这是一个有趣的黑客攻击,可能暂时还需要这个答案的第二部分,而且,即使使用文件列表构造函数,它仍然是有效的:您将无法修改文件列表,只能创建新的。@kaido不幸的是,我们仍然无法在Safari(可能还有IE/Edge)中创建新的
DataTransfer
,对吗?@mb21我最近没有在Edge中检查,但是的,据我所知,只有Chrome已经开始实施DataTransfer构造函数,FF漏洞仅在FF上有效。顺便说一句,你所做的错误报告链接到