8

I figure I'd demonstrate the problem with an example first,

jsfiddle: http://jsfiddle.net/e2UfM/15/ (Tested with FF 12, and Chrome 18.0.1025.168)

Usage:

  • Load in a text file from your local machine.
  • Hit "load file".
  • Hit "display file size" - note the size.
  • modify & save the text file on your local machine.
  • Hit "display file size" again. Note how in webkit browsers (Chrome) the file size changes, but in Firefox it didn't update the file size

Non-webkit browsers do not update their size attribute when users make changes to the local file that they have selected whereas Chrome for example does. Both browsers update the contents of the file.

Is there a way to get Firefox to update the file size similar to how Chrome does in this situation?


Simple Real World Example:

User selects a file that's too large for the form, they hit the submit button and get notified that their file is too large (via an alert, "size" bar (see below), etc)

They modify the file locally, and hit submit again.

In Chrome, the file size updates. When the user hits the submit button again, it will validate it's updated size once more and allow the upload. In Firefox, the user must re-select the file on the form before it will see the file size change.

A partial workaround for Firefox - @ZER0's answer


Real world example (in-depth):

One purpose of the File API is to verify file sizes on the client side before uploading to a server if I'm not mistaken.

Consider the scenario where there is a 2MB upload limit in a form and the user chooses a 1MB file. Both Firefox and Chrome will see that the file size is less than 2MB and add it to the form. Let's also say there is a neat bar that shows how big of a file they have chosen, and if it meats the file size limit or not:

The 1MB file that the user has chosen!

But then the user decides to make a minor change to the contents of that file locally before they submit the form and bump the size over 2MB.

In Google Chrome, I can handle this gracefully on the client side. I can check the file size again when the user submits the form, and verify that it is still in fact under 1MB before sending it to the server. But even before the user submits the form, in Chrome, I can go as far as updating the little bar image dynamically as they make changes locally as such:

Now the file is over 2MB, bad!

This "bar" (or any other form on instant notification such as an alert) is useful if the user is filling out a large form. I'd like the user to know instantly when their file is too large and so that they can correct it then, and not just when they submit the form.

In Firefox, because the file size never updates, it will gladly upload the 2MB file thinking that it is still 1MB! I use server side logic to double check the file size, but I'd rather save a server trip.


How I came across the bug:

The above examples are in place to relate to more people as more people have probably dealt with file uploads in forms vs. using the slice function in the File API. This is specifically how I am running into the issue.

In my form, the user selects a file and when they hit submit only the last 10,000 bytes are displayed on the screen in a textarea to confirm that it's really the file that they want.

Consider a file with a size of 50,000 bytes. A user chooses it in the form, and both Chrome and Firefox show bytes 40,000 - 50,000 in the textarea.

Now the user adds some content to the file, and bumps the same file to 70,000 bytes!

Google Chrome will properly update the textarea to contain bytes 60,000-70,000. In Firefox, because the size will remain constant, it will still only show bytes in the range 40,000-50,000.


Edit: Updated the jsfiddle to demonstrate that FF can still read the updated file contents. It's just that the file size does not change with those new contents.

Edit: https://bugzilla.mozilla.org/show_bug.cgi?id=756503 (bug report)

Edit: Examples have been added & updated in response to @Eduárd Moldován's comment & @ZER0's answer. Thanks!

Community
  • 1
  • 1
Jay
  • 18,959
  • 11
  • 53
  • 72
  • 3
    Once you load the file, there should be no connection remaining to the original file on disk. You should be operating on a copy of the contents. IMHO, this is a security risk for Chrome. – Steve H. May 21 '12 at 21:17
  • 1
    Yes, but even in Firefox you are able to read from the File after the initial load and get the updated contents of the file, but the file _size_ does not update. If I'm validating the size of a file before uploading it to a server, an actual size would be useful - not just the initial "copy" size. – Jay May 21 '12 at 21:32
  • I'll update the OP, http://jsfiddle.net/e2UfM/15/ Thanks @SteveH. – Jay May 21 '12 at 21:39
  • What is the scope of this? Why do you need to know if file size changes after it has been selected? – albanx Jun 01 '12 at 12:05
  • @albanx I've updated the OP with an example. – Jay Jun 01 '12 at 17:47
  • You should always check on the server too. A user could just disable JS to upload a larger file. You should probably file a bugreport for firefox. – Gerben Jun 01 '12 at 19:02
  • Of course - server side checking is a must :) I filed a bug report awhile back, [Bug 756503](https://bugzilla.mozilla.org/show_bug.cgi?id=756503), but just wanted to ask here for any possible workarounds. Thanks. – Jay Jun 01 '12 at 19:47
  • I would do things a bit differently. Why not check the size only on submit? – Eduárd Moldován Jun 04 '12 at 20:41
  • @EduárdMoldován When checking on submit, what happens if the file is too large? The user may try and modify their files size, and hit submit again, but only Chrome will see that they have made changes and allow for it. Granted most users would re-select their file in the form (which would work), but that is an annoyance. Thanks for your question - updated the OP :) – Jay Jun 04 '12 at 22:38
  • @Trevor Senior: Then just set a timer and reinitialize the object each time. – Eduárd Moldován Jun 05 '12 at 22:16
  • Can you elaborate or provide an example? I'll try some things and see if I can get it working in this way. – Jay Jun 06 '12 at 01:51

1 Answers1

1

It seems that you're get the size property from the directly, and because the value in this form element is not changed it's likely that Firefox doesn't update the size property as well.

As workaround, you can check the length of the content you have read. So instead of file.size have evt.target.result.length.

However, it's definitely a bug to me so you have done well to add it on Bugzilla!

Update: You can still use the string version of slice. Otherwise, if you prefer (or the result is a particular type of data), you can create from evt.target.result a new Blob object (The File Object use this interface) where you can use both size property and slice method.

ZER0
  • 24,846
  • 5
  • 51
  • 54
  • +1 Great workaround - Checking if the length has changed allows one to alert the user (in FF) to update the form field. However, I failed to mention I am using [File API's slice](http://www.w3.org/TR/FileAPI/#slide-method-algo) to snag the last 10,000 bytes of a file. I was keeping the question simple and omitted that, but I'll add it in now as a third example! Thanks for your answer. – Jay Jun 06 '12 at 02:01
  • Thanks for the update! This is an ever *better* workaround and I can remove some ugly bits of code that I've written. – Jay Jun 11 '12 at 22:10