8

我想我会先用一个例子来证明这个问题,

jsfiddle: http: //jsfiddle.net/e2UfM/15/ (使用 FF 12 和 Chrome 18.0.1025.168 测试)

用法:

  • 从本地计算机加载文本文件。
  • 点击“加载文件”。
  • 点击“显示文件大小” - 注意大小。
  • 在本地机器上修改并保存文本文件。
  • 再次点击“显示文件大小”。请注意在 webkit 浏览器 (Chrome) 中文件大小如何变化,但在 Firefox 中它没有更新文件大小

当用户更改他们选择的本地文件时,非 webkit 浏览器不会更新其大小属性,而 Chrome 会这样做。两种浏览器都会更新文件的内容。

有没有办法让 Firefox 更新文件大小,就像 Chrome 在这种情况下所做的那样?


简单的真实世界示例:

用户选择了一个对于表单来说太大的文件,他们点击提交按钮并收到通知他们的文件太大(通过警报、“大小”栏(见下文)等)

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

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

Firefox 的部分解决方法 - @ZER0 的回答


真实世界的例子(深入):

如果我没记错的话,文件 API 的一个目的是在上传到服务器之前验证客户端的文件大小。

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

用户选择的 1MB 文件!

但是随后用户决定在提交表单并将大小超过 2MB之前在本地对该文件的内容进行微小的更改。

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

现在文件超过 2MB,糟糕!

如果用户正在填写大型表单,则此“栏”(或即时通知上的任何其他表单,例如警报)很有用。我希望用户在他们的文件太大时立即知道,以便他们可以更正它,而不仅仅是在他们提交表单时。

在 Firefox 中,因为文件大小永远不会更新,它会很乐意上传 2MB 的文件,认为它仍然是 1MB!我使用服务器端逻辑来仔细检查文件大小,但我宁愿节省服务器行程。


我是如何遇到这个错误的:

上述示例与更多人相关,因为更多人可能处理过表单中的文件上传,而不是使用File API 中的 slice 函数。这就是我遇到问题的具体方式。

在我的表单中,用户选择了一个文件,当他们点击提交时,屏幕上只显示最后 10,000 个字节,textarea以确认它确实是他们想要的文件。

考虑一个50,000字节大小的文件。用户在表单中选择它,Chrome 和 Firefox 都40,000 - 50,000textarea.

现在用户向文件添加了一些内容,并将相同的文件转换为70,000字节!

Google Chrome 将正确更新textarea以包含 bytes 60,000-70,000。在 Firefox 中,因为大小将保持不变,它仍然只会显示范围内的字节40,000-50,000


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

编辑: https ://bugzilla.mozilla.org/show_bug.cgi?id=756503 (错误报告)

编辑:已添加和更新示例以响应@Eduárd Moldován 的评论和@ZER0 的回答。谢谢!

4

1 回答 1

1

看来您是size直接从那里获取属性的,并且由于此表单元素中的值没有更改,因此 Firefox 可能也不会更新该size属性。

作为解决方法,您可以检查length您已阅读的内容。所以而不是file.sizeevt.target.result.length.

但是,这对我来说绝对是一个错误,因此您将其添加到 Bugzilla 上已经做得很好了!

更新:您仍然可以使用slice的字符串版本。否则,如果您更喜欢(或者result是特定类型的数据),您可以从evt.target.result一个新的Blob对象(文件对象使用此接口)创建,您可以在其中使用size属性和slice方法。

于 2012-06-05T21:37:56.140 回答