Javascript FileAPI没有';t在用户更改文件时更新文件大小(非webkit浏览器)

Javascript FileAPI没有';t在用户更改文件时更新文件大小(非webkit浏览器),javascript,html,firefox,webkit,fileapi,Javascript,Html,Firefox,Webkit,Fileapi,我想我先用一个例子来说明这个问题 jsfiddle: (使用FF 12和铬18.0.1025.168进行测试) 用法: 从本地计算机加载文本文件 点击“加载文件” 点击“显示文件大小”-注意大小 在本地计算机上修改并保存文本文件 再次点击“显示文件大小”。请注意,在webkit浏览器(Chrome)中,文件大小是如何变化的,但在Firefox中,它没有更新文件大小 当用户更改他们选择的本地文件时,非webkit浏览器不会更新其大小属性,而Chrome浏览器就是这样做的。两种浏览器都会更新文件

我想我先用一个例子来说明这个问题

jsfiddle: (使用FF 12和铬18.0.1025.168进行测试)

用法:

  • 从本地计算机加载文本文件
  • 点击“加载文件”
  • 点击“显示文件大小”-注意大小
  • 在本地计算机上修改并保存文本文件
  • 再次点击“显示文件大小”。请注意,在webkit浏览器(Chrome)中,文件大小是如何变化的,但在Firefox中,它没有更新文件大小
当用户更改他们选择的本地文件时,非webkit浏览器不会更新其大小属性,而Chrome浏览器就是这样做的。两种浏览器都会更新文件的内容

有没有办法让Firefox更新类似Chrome在这种情况下的文件大小


简单的现实世界示例: 用户选择一个对表单来说太大的文件,他们点击提交按钮,并得到文件太大的通知(通过一个警告,“大小”栏(见下文)等)

他们在本地修改文件,然后再次点击提交

在Chrome中,文件大小会更新。当用户再次点击提交按钮时,它将再次验证其更新的大小并允许上传。在Firefox中,用户必须重新选择表单上的文件,然后才能看到文件大小的更改

Firefox-@ZER0的部分解决方案


真实世界示例(深入): 文件API的一个用途是在上传到服务器之前验证客户端上的文件大小(如果我没有弄错的话)

考虑这样一个场景:表单中有2MB上传限制,用户选择1MB文件。Firefox和Chrome都会看到文件大小小于2MB,并将其添加到表单中。我们还可以说,有一个整洁的栏,显示他们选择的文件有多大,以及是否符合文件大小限制:

但是,用户决定在提交表单并将大小增加到2MB之前,在本地对该文件的内容做一个小的更改

在Google Chrome中,我可以在客户端优雅地处理这个问题。当用户提交表单时,我可以再次检查文件大小,并在将表单发送到服务器之前验证它是否仍然低于1MB。但即使在用户提交表单之前,在Chrome中,我也可以动态更新小条图像,因为他们在本地进行更改,例如:

如果用户填写大表单,此“栏”(或任何其他即时通知表单,如警报)非常有用。我想让用户立即知道他们的文件什么时候太大,这样他们就可以更正它,而不仅仅是在他们提交表单的时候

在Firefox中,由于文件大小从未更新,它会很高兴地上传2MB文件,认为它仍然是1MB!我使用服务器端逻辑来双重检查文件大小,但我宁愿保存一次服务器跳闸


我是如何遇到这个错误的: 上面的例子与更多的人相关,因为可能有更多的人使用表单处理文件上传,而不是使用。这就是我遇到这个问题的具体方式

在我的表单中,用户选择一个文件,当他们点击submit时,屏幕上的
textarea
中只显示最后10000字节,以确认这确实是他们想要的文件

考虑大小为
50000
字节的文件。用户在表单中选择它,Chrome和Firefox都会在
文本区域中显示字节
40000-50000

现在,用户向文件中添加了一些内容,并将同一文件压缩到
70000
字节

Google Chrome将正确更新
textarea
以包含字节
60000-70000
。在Firefox中,由于大小将保持不变,它仍然只显示范围
40000-50000
内的字节


编辑:更新了JSFIDLE,以证明FF仍然可以读取更新的文件内容。只是文件大小不会随着这些新内容而改变

编辑:(错误报告)


编辑:已添加并更新示例,以响应@Eduárd Moldován和@ZER0。谢谢

您似乎直接从中获得了
size
属性,而且由于表单元素中的值没有更改,因此Firefox很可能也不会更新
size
属性

作为解决方法,您可以检查所阅读内容的
长度。因此,不要使用
file.size
而是使用
evt.target.result.length

然而,这对我来说绝对是一个bug,所以你把它添加到Bugzilla上做得很好

更新
您仍然可以使用的字符串版本。否则,如果您愿意(或者
结果
是一种特定类型的数据),您可以从
evt.target.result
创建一个新对象(文件对象使用此界面),在这里您可以使用
大小
属性和
切片
方法,应该没有与磁盘上原始文件的连接。你应该在内容的副本上操作。这对Chrome来说是一个安全风险。是的,但即使在Firefox中,你也可以在初始加载后读取文件并获取文件的更新内容,但文件大小不会更新。如果我在上传到服务器之前验证文件的大小,那么实际大小将非常有用-不仅仅是初始的“副本”大小。我将更新OP,谢谢@SteveH。这是什么范围?为什么你需要知道文件大小在被选中后是否会改变?@albanx我已经用一个例子更新了OP。+1很好的解决方法-检查长度是否改变可以提醒用户(在FF中)更新表单字段。然而,我没有提到我正在使用的最后一个障碍