我想我先用一个例子来演示这个问题,
jsfiddle:http://jsfiddle.net/e2UfM/15/
(已测试FF 12和Chrome 18.0.1025.168)
用法:
当用户对他们选择的本地文件进行更改时,非Webkit浏览器不会更新其size属性,而例如Chrome浏览器会进行更新。两种浏览器都更新文件的内容。
有没有办法让Firefox更新文件大小,类似于在这种情况下Chrome所做的事情?
简单的真实世界示例:
用户选择的文件对于表单而言太大,他们点击了“提交”按钮,并收到有关其文件太大的通知(通过警报,“大小”栏(如下所示)等)
他们在本地修改文件,然后再次点击“提交”。
在Chrome中,文件大小会更新。当用户再次点击提交按钮时,它将再次验证其更新大小并允许上传。在Firefox中,用户必须重新选择表单上的文件,然后文件大小才会更改。
Firefox的部分解决方法-@ ZER0的answer
真实示例(深入):
File API的一个目的是,如果我没有记错的话,请先在客户端上验证文件大小,然后再上传到服务器。
考虑以下情况:表单中的上传限制为2MB,而用户选择一个1MB的文件。 Firefox和Chrome都将看到文件大小小于2MB,并将其添加到表单中。我们还假设有一个整洁的条形图,显示了他们选择的文件大小,以及该文件是否超出了文件大小限制:
但是,然后用户决定在提交表单并将文件大小增加到2MB以上之前,对本地对该文件的内容进行较小的更改。
在Google Chrome浏览器中,我可以在客户端正常处理此问题。我可以在用户提交表单时再次检查文件大小,并在将其发送到服务器之前确认它实际上仍在1MB以下。但是,即使在用户提交表单之前,在Chrome中,我仍然可以动态地更新小条图像,因为它们在本地进行了如下更改:
如果用户填写大表格,则此“栏”(或即时通知上的任何其他表格,例如警报)很有用。我希望用户立即知道他们的文件何时过大,以便他们可以进行更正,而不仅仅是在提交表单时。
在Firefox中,由于文件大小永远不会更新,因此它会很高兴地上传2MB的文件,以为它仍然是1MB!我使用服务器端逻辑来仔细检查文件大小,但是我宁愿节省服务器行程。
我是如何发现该错误的:
上面的示例与更多的人相关,因为与slice function in the File API相比,更多的人可能已经处理了表单上载的文件。这就是我遇到问题的方式。
在我的表单中,用户选择一个文件,当他们单击“提交”时,仅最后10,000个字节以
textarea
的形式显示在屏幕上,以确认它确实是他们想要的文件。考虑一个大小为
50,000
字节的文件。用户以表格的形式选择它,Chrome和Firefox都在40,000 - 50,000
中显示字节textarea
。现在,用户将一些内容添加到文件中,并将同一文件增加到
70,000
字节!Google Chrome浏览器将正确更新
textarea
,使其包含字节60,000-70,000
。在Firefox中,由于大小将保持不变,因此仍仅显示40,000-50,000
范围内的字节。编辑:更新了jsfiddle,以演示FF仍可以读取更新的文件内容。只是文件大小不会随这些新内容而改变。
编辑: https://bugzilla.mozilla.org/show_bug.cgi?id=756503(错误报告)
编辑:已添加和更新示例,以响应@EduárdMoldován的comment和@ ZER0的answer。谢谢!
最佳答案
看来您直接从那里获得了size
属性,并且由于此form元素中的值未更改,因此Firefox可能也不会更新size
属性。
解决方法是,您可以检查已阅读内容的length
。因此,请使用file.size
代替evt.target.result.length
。
但是,对我来说,这绝对是个错误,因此,您可以很好地在Bugzilla上添加它!
更新:
您仍然可以使用slice的字符串版本。否则,如果您愿意(或result
是一种特殊的数据类型),则可以从evt.target.result
创建一个新的Blob对象(File对象使用此接口(interface)),在其中可以同时使用size
属性和slice
方法。
关于javascript - 用户进行文件更改(非Webkit浏览器)时,FileAPI不会更新文件大小,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10646601/