Brian Duncan
Brian Duncan

Reputation: 1186

Blueimp jQuery File Upload plugin - "Empty file upload" result PHP

Here's the plugin: https://github.com/blueimp/jQuery-File-Upload

I'm having a problem getting the response I want from the plugin after uploading a file.

On the page with the plugin, I have the following

$('#fileupload').fileupload(
    'option',
    {
        'maxNumberOfFiles' :1,
        'url' : '/admin/upload_handler.php'
    }
);

In upload_handler.php I successfully retrieve the uploaded files from $_FILES and do stuff, then send a response back in JSON. I've confirmed using Firebug that the response is in the proper format:

[ 
    {                
        "url" : "image_url",
        "thumbnail_url" : "image_th_url",
         "delete_url" : "test",
         "delete_type" : "DELETE",
         "name" : "foobar.jpg",
         "size" : 7419
     }
]

But the callback can't find the files array, and I get the error: 'Empty file upload result'. I feel like I'm missing something crucial here--I can't find anything in the docs, forums, or Stack Overflow. I appreciate any help.

Upvotes: 9

Views: 22046

Answers (7)

user3190790
user3190790

Reputation: 1

For me it was the uploads file size. i tuned those php.ini parameters:

  • memory_limit
  • post_max_size
  • upload_max_filesize
  • max_file_uploads

Upvotes: 0

Giorgio Minardi
Giorgio Minardi

Reputation: 2775

As mentioned before this happens because the server response is not what the plugin expects (which is a files array as shown here). If you don't (or cannot) want to change the backend, a solution is to replace the result object in the response with the result object the plugin expects (which then contains the files array).

This can be done in the fileuploaddone event.

Let's assume that this is the JSON response returned from the server once the upload is done: enter image description here

data.result holds the server response:

.bind('fileuploaddone', function(e, data) {
    //this will now contains the server response 
    //as per the attached image: an array of elements
    data.result;
});

We want to replace the result object with a new one that can be parsed by the blueimp plugin, let's define it (note: this is an object that contains an array of files, as per the plugin docs).

//tempFolder is optional
var filesUploaded = { "files": [], "tempFolder": null };

Replacing the result object:

.bind('fileuploaddone', function(e, data) {
    //creating a file object in the format the jquery plugin is expecting
    var file = {
        deleteType: "DELETE",
        deleteUrl:"#",
        type: data.result[0].MimeType,
        thumbnailUrl : "#",
        url: "#",
        name: data.result[0].Name,
        size: data.result[0].Size
    }

    //adding it to the file list
    filesUploaded.files.push(file);
    data.result = null;
    //replacing the server response with the 'custom' one we just created
    data.result = filesUploaded;
});

The plugin should now render fine as it will be parsing the expected JSON schema and you won't get the "Empty file upload result" message anymore.

Upvotes: 0

Kareem Cambridge
Kareem Cambridge

Reputation: 21

In my case I, i modified the jquery.fileupload-ui.js file to look for the JSON result directly.

Change this snippet

  if (data.context) {
                    data.context.each(function (index) {
                        var file = files[index] ||
                                {error: 'Empty file upload result'};//CHANGE
                        deferred = that._addFinishedDeferreds();
                        that._transition($(this)).done(
                            function () {

To This

  if (data.context) {
                    data.context.each(function (index) {
                        var file = data._response.result[index] ||
                                {error: 'Empty file upload result'};//TO THIS
                        deferred = that._addFinishedDeferreds();
                        that._transition($(this)).done(
                            function () {

Upvotes: 0

reidLinden
reidLinden

Reputation: 4160

Your return needs to be enclosed in a files array, like this:

    {"files": [
      {
        "name": "picture1.jpg",
        "size": 902604,
        "url": "http:\/\/example.org\/files\/picture1.jpg",
        "thumbnailUrl": "http:\/\/example.org\/files\/thumbnail\/picture1.jpg",
        "deleteUrl": "http:\/\/example.org\/files\/picture1.jpg",
        "deleteType": "DELETE"
      },
      {
        "name": "picture2.jpg",
        "size": 841946,
        "url": "http:\/\/example.org\/files\/picture2.jpg",
        "thumbnailUrl": "http:\/\/example.org\/files\/thumbnail\/picture2.jpg",
        "deleteUrl": "http:\/\/example.org\/files\/picture2.jpg",
        "deleteType": "DELETE"
      }
    ]}

in particular, the requirement is: Note that the response should always be a JSON object containing a files array even if only one file is uploaded.

via :: https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#using-jquery-file-upload-ui-version-with-a-custom-server-side-upload-handler

Upvotes: 4

PERPO
PERPO

Reputation: 3822

Since the version 5 of the plugin, the json response has changed: https://github.com/blueimp/jQuery-File-Upload/wiki/JSON-Response

So you just have tweak your upload class with:

$filejson = new stdClass();
$filejson->files[] = $fileArray;
return json_encode($filejson);

And you're done

Upvotes: 4

user2405413
user2405413

Reputation:

The "Empty file upload result" will occur when adding HTML (and in programmatical result DOM) objects to the template that are outside of the <tr class="template-upload fade"> HTML tag, e.g.: let's say you add another <tr> to the template

This will result in the file(s) being uploaded correctly and for every uploaded file you will get the "Empty file upload result" once.

Seems to have to do something with the JS template engine.

This can be fixed in jquery.fileupload-ui,js, right after line 128

Original code:

    // Callback for successful uploads:
done: function (e, data) {
    var that = $(this).data('blueimp-fileupload') ||
            $(this).data('fileupload'),
        files = that._getFilesFromResponse(data),
        template,
        deferred;
    if (data.context) {
        data.context.each(function (index) { // LINE 128
            var file = files[index] ||
                    {error: 'Empty file upload result'},
                deferred = that._addFinishedDeferreds();

Add the following code after line 128:

if (!$(data.context[index]).hasClass(that.options.uploadTemplateId)) { return true; }

Resulting code:

    // Callback for successful uploads:
done: function (e, data) {
    var that = $(this).data('blueimp-fileupload') ||
            $(this).data('fileupload'),
        files = that._getFilesFromResponse(data),
        template,
        deferred;
    if (data.context) {
        data.context.each(function (index) { //LINE 128
            if (!$(data.context[index]).hasClass(that.options.uploadTemplateId)) { return true; } // YOUR ADDED LINE
            var file = files[index] ||
                    {error: 'Empty file upload result'},
                deferred = that._addFinishedDeferreds();

Hope this helps others :)

Upvotes: 2

pop
pop

Reputation: 3704

OK, this seems like it is not a jQuery problem, but rather a server-side issue. In my case it is a PHP script, which needed tweaking as follows.

See function post(), edit this line

$json = json_encode($info);

to

$json = json_encode(array($this->options['param_name'] =>$info));

and I had to also edit the echo at the last line of the function; instead of

echo $json;

there is now

echo str_replace('\/','/',$json);

It seems to work fine returning a correct json array. Hope it helps.

Upvotes: 0

Related Questions