jQuery-File-Upload icon indicating copy to clipboard operation
jQuery-File-Upload copied to clipboard

Android (default browser) sends Blobs as empty files (e.g. using Chunked Uploads)

Open cbepxpa3ym opened this issue 11 years ago • 20 comments

Do not work. Gives error: File is too small

cbepxpa3ym avatar Dec 17 '12 17:12 cbepxpa3ym

Android only supports XHR style uploads from version 3.2+ onwards, but not chunked uploads: https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support

blueimp avatar Dec 18 '12 10:12 blueimp

I understand, but in this case the script should use non-chunked upload automaticaly.

P. S. No need to post the links from your documentation. I read it already few times. Count me as your bug-tester :) So, I am not asking you to add ability for chunked upload, I am just telling you it fails, instead of use a non-chunked upload.

cbepxpa3ym avatar Dec 18 '12 10:12 cbepxpa3ym

Yeah, that's why I reopened this issue. However, this might be tricky, as the Android browser passes all checks for chunked uploads, but doesn't properly implement it, it seems.

Thanks for bug testing anyway! :)

blueimp avatar Dec 18 '12 10:12 blueimp

OK, I had a look into this issue and unfortunately this is a bug in the Blob API implementation of Android. The worst news is that there is no feature detection possible to detect this bug, before making the actual request.

Here are the related issues on the Android issues tracker: http://code.google.com/p/android/issues/detail?id=22441 http://code.google.com/p/android/issues/detail?id=36524

Please star those issues and add your voice so this problem will get fixed by the Android developers.

blueimp avatar Dec 18 '12 11:12 blueimp

What about a temporary hardcoded check of platform and browser to disable Chunked Uploads?

cbepxpa3ym avatar Dec 18 '12 13:12 cbepxpa3ym

Since chunked uploads are not enabled by default, I would rather suggest, you enable it with a condition, like this:

$('#fileupload').fileupload('option', 'maxChunkSize', !navigator.userAgent.match(/Android/i) && 200000);

blueimp avatar Dec 18 '12 13:12 blueimp

Btw, the one reason I would use chunked upload is to avoid php.ini max upload size error. So, I have 120M as a limit in my php.ini, but I can upload let's say a movie of 1.4 GB with chunked upload (I set to a bit smaller value than max upload size limit). I calculate it automatically with your function get_config_bytes, where I changed 1024 into 1000 to get smaller results. So, it returns 120 000 000 instead of 125 829 120 (5 MB less). So, in this case I will never get an empty $_FILES array (with browsers which are compatible with chunked upload of course).

cbepxpa3ym avatar Dec 18 '12 14:12 cbepxpa3ym

I explicitly disabled chunked uploads for all browsers both passing the options directly as setting the option after, but am still getting empty files on the server when uploading from android 4.0.4 browser. $('.add_file_btn input').fileupload('option', 'maxChunkSize', false);

File 'Blob5...' is no image, 'application/x-empty' detected.

Hampei avatar Jan 27 '13 22:01 Hampei

Can you reproduce this issue on the demo?

blueimp avatar Jan 27 '13 22:01 blueimp

Yes. The demo says Blob.... 0.00KB file is too small.

It looks like it's trying too upload chunked anyway. On the server side I get things like: [name] => Blob2165f4008f714f1f94e734973277a1da [type] => application/x-empty [tmp_name] => /tmp/phpa5FRB6 [error] => 0 [size] => 0 [options] => Array

That the request is saying the file is 0 bytes seems to be a known problem for chunked uploads. But the file is actually being uploaded if look at the time it takes to finish the request.

Hampei avatar Jan 27 '13 23:01 Hampei

OK, the demo does make use of client-side image resizing, which also creates Blobs, which are also incorrectly handled by Android. So if this issue is the same as on your setup, if you want to support Android, you'll have to disable both chunked uploads as well as client-side image resizing or any other method that doesn't transfer the original File objects.

blueimp avatar Jan 27 '13 23:01 blueimp

Thank you. I was resizing the image client side. disabling that it now works.

Hampei avatar Jan 27 '13 23:01 Hampei

Is there any possibility to send the file chunk as base64 encoded string, since android browser can handle readAsUrlData? By the way the chrome android version does not have this bug.

albanx avatar Apr 15 '13 14:04 albanx

Since both Opera 12 and the default Android browser (but not Chrome on Android) suffer from this bug, which unfortunately cannot be feature tested without involving an actual request to the server, I recommend the following check before enabling chunked uploads or client-side image resizing:

var supportsBlobXHR = !/Android(?!.*Chrome)|Opera/.test(window.navigator && navigator.userAgent)

blueimp avatar Jun 12 '13 11:06 blueimp

Hi Blueimp, I am just starting in learning java programming, for my school assignment purpose, I am using your upload plugin in my school project. However, I meet the same issues as above. Client-side image resizing is very important to my project, I can't disable it for some purpose. After study on the issues some time, as your mentioned, image resizing is function well in android default browser, the roof cause should be on the sending blob with xhr. In my studying on this, I have found some useful information from the link in below,

  • https://github.com/joelvardy/javascript-image-upload
  • http://ghinda.net/jpeg-blob-ajax-android/

From the link, I come out two idea,

  1. Convert the blob to arraybuffer before send with xhr. This is work with a simple testing in http://ghinda.net/jpeg-blob-ajax-android/.

  2. Combine the programming concept of file upload from https://github.com/joelvardy/javascript-image-upload to the plugin, since they are worked in android default browser.

I have study on the java code in your plugin, but I don't how to modify it with potential solution in above for testing, thus, I really need your help for it for me to implement them in my project.

Sorry about that my english is poor because english not my language. Hope to get your response as soon as possible.

valencet avatar Mar 18 '14 10:03 valencet

Thanks for your comment, @valencet.

The ArrayBuffer workaround explained here is indeed new to me and valuable information.

Unfortunately the transformation from a Blob to an ArrayBuffer is an asynchronous operation, else we could simply adjust the _initXHRData method, which sets up the XHR data to sent to the server (either the File or Blob as is, or wrapped in a FormData object).

As it is now, the code depending on the _initXHRData method expects a synchronous response. Although it's certainly possible to change that, it would require a significant refactoring of the core code base.

blueimp avatar Mar 18 '14 23:03 blueimp

Added a pull request with a fix for this: https://github.com/blueimp/jQuery-File-Upload/pull/3052

DarrenInwood avatar Mar 25 '14 21:03 DarrenInwood

@DarrenInwood Have you been using your fork in production at all? I'm debating how to approach this issue. I'm leaning towards rolling my own base64 method.

rdetert avatar Jul 07 '14 01:07 rdetert

@rdetert Yes we've been using this in production, it works fine. :-)

DarrenInwood avatar Jul 07 '14 02:07 DarrenInwood

@DarrenInwood Does your fork works with the ImageResize option ? I've tested it, and it doesn't seem to work...

chandon avatar Jul 15 '14 22:07 chandon