Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery file upload: cannot upload file in Safari 11

Steps to reproduce the bug in Safari 11:

  1. Create a folder with Cyrillic letters in the title, for example "русский_язык"
  2. Add some files to the folder
  3. Open https://blueimp.github.io/jQuery-File-Upload/ in Safari 11.1 browser
  4. Upload file from that folder

Actual result: file was not uploaded.

For a better understanding, watch the video for Safari 11: https://drive.google.com/open?id=16tU8iBn0U9bUs7u5pM4ZBXmxpfJIv8WV

Try to upload the same file but use Safari 10.

Actual result: all is good, file was uploaded without any problems.

For a better understanding, watch the video for Safari 10: https://drive.google.com/open?id=1IO--Y1RjETAYAucaNyqhM6HZcQdNKDkI

Update 28.05.2018 After a few hours of debagging via crossbrowsertesting.com (because I do not have safari) I found temporary solution: on this line https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.fileupload.js#L1182 need to replace

entries = fileInput.prop('webkitEntries') ||  fileInput.prop('entries')

to

entries = []

And everything should works.

I guess it happened becasuse apple added to safari experimental feature - FileSystemEntry. More info about this feature https://developer.mozilla.org/en-US/docs/Web/API/FileSystemEntry.

If entries variable will be empty jquery.fileupload.js will use well-tried files attribute for getting uploaded files. Look to code https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.fileupload.js#L1189 for more details

Also I report a bug to Safari and to Sebastian Tschan (author of this library)

like image 618
Vladimir Kalyuzhny Avatar asked Apr 19 '18 10:04

Vladimir Kalyuzhny


1 Answers

I found the same problem now. I have already detected that the code snippet: jquery.fileupload.js

_handleFileTreeEntry: function (entry, path) {
        var that = this,
            dfd = $.Deferred(),
            errorHandler = function (e) {
                if (e && !e.entry) {
                    e.entry = entry;
                }
                // Since $.when returns immediately if one
                // Deferred is rejected, we use resolve instead.
                // This allows valid files and invalid items
                // to be returned together in one set:
                dfd.resolve([e]);
            },
            successHandler = function (entries) {
                that._handleFileTreeEntries(
                    entries,
                    path + entry.name + '/'
                ).done(function (files) {
                    dfd.resolve(files);
                }).fail(errorHandler);
            },
            readEntries = function () {
                dirReader.readEntries(function (results) {
                    if (!results.length) {
                        successHandler(entries);
                    } else {
                        entries = entries.concat(results);
                        readEntries();
                    }
                }, errorHandler);
            },
            dirReader, entries = [];
        path = path || '';
        if (entry.isFile) {
            if (entry._file) {
                // Workaround for Chrome bug #149735
                entry._file.relativePath = path;
                dfd.resolve(entry._file);
            } else {
                entry.file(function (file) {  // <=== here
                    file.relativePath = path;
                    dfd.resolve(file);
                }, errorHandler);
            }
        } else if (entry.isDirectory) {
            dirReader = entry.createReader();
            readEntries();
        } else {
            // Return an empy list for file system items
            // other than files or directories:
            dfd.resolve([]);
        }
        return dfd.promise();

}

in this function, when the code run into the condition

            entry.file(function (file) {
                file.relativePath = path;
                dfd.resolve(file);
            }, errorHandler);

Safari is return the errorHandler for the file function callback. the function api reference here: https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileEntry/file.

It must be Safari 11's bug. After soon I will report the bug for Apple. In jQuery.fileupload.js, I guess the better fixed method is detect the UserAgent with Safari 11. But I think Apple should fix this problem.

like image 164
Stevenhong Avatar answered Nov 15 '22 07:11

Stevenhong