开发者

multiple file upload using html5 drag-and-drop fails as multiple files get same content

开发者 https://www.devze.com 2023-03-10 05:44 出处:网络
I need to transfer all the files dropped on an element to a server using HTML5 drag and drop. I provided the corresponding js code below. I have a servlet in the server side to collect the files and p

I need to transfer all the files dropped on an element to a server using HTML5 drag and drop. I provided the corresponding js code below. I have a servlet in the server side to collect the files and put it in a folder. This is working fine if I drop 1 or 2 files on the page. But, if i drop 4-10 files, all the files are getting created in the server but multiple files are set to same content and some files content is 0K.

Can any of you please tell me how to achieve the correct behavior. My requirement is similar to gmail attachments!! Any solution which makes a sequential upload of files is much appreciable.

/*
 *  Upload files to the server using HTML 5 Drag and drop from the folders on  your     local computer
*/

function uploader(place, status, target, show) {

// Upload image files
upload = function(file) {
    // Firefox 3.6, Chrome 6, WebKit
    if(window.FileReader) { 

        // Once the process of reading file
        this.loadEnd = function() {
            bin = reader.result;                
            xhr = new XMLHttpRequest();
            xhr.open('POST', target+'?up=true', false);
            var body = bin;
            xhr.setRequestHeader('content-type', 'multipart/form-data;');
            xhr.setRequestHeader("file-name", file.name );
            xhr.setRequestHeader("mime-type", file.type );

            // Firefox 3.6 provides a feature sendAsBinary ()
            if(xhr.sendAsBinary != null) { 
                xhr.sendAsBinary(body); 
            // Chrome 7 sends data but you must use the base64_decode on the PHP side
            } else { 
                xhr.open('POST', target+'?up=true&base64=true', true);
                xhr.setRequestHeader('UP-FILENAME', file.name);
                xhr.setRequestHeader('UP-SIZE', file.size);
                xhr.setRequestHeader('UP-TYPE', file.type);
                xhr.send(window.btoa(bin));
            }
            if (show) {
                var newFile  = document.createElement('div');
                newFile.innerHTML = 'Loaded : '+file.name+' size '+file.size+' B';
                document.getElementById(show).appendChild(newFile);             
            }
            if (status) {
                document.getElementById(status).innerHTML = 'Loaded : 100%<br/>Next file ...';
            }
        };

        // Loading errors
        this.loadError = function(event) {
            switch(event.target.error.code) {
                case event.target.error.NOT_FOUND_ERR:
                    document.getElementById(status).innerHTML = 'File not found!';
                break;
                case event.target.error.NOT_READABLE_ERR:
                    document.getElementById(status).innerHTML = 'File not readable!';
                break;
                case event.target.error.ABORT_ERR:
                break; 
                default:
                    document.getElementById(status).innerHTML = 'Read error.';
            }   
        };

        // Reading Progress
        this.loadProgress = function(event) {
            if (event.lengthComputable) {
                var percentage = Math.round((event.loaded * 100) / event.total);
                document.getElementById(status).innerHTML = 'Loaded : '+percentage+'%';
            }               
        };

        // Preview images
        this.previewNow = function(event) {     
            bin = preview.result;
            var img = document.createElement("img"); 
            img.className = 'addedIMG';
            img.file = file;   
            img.src = bin;
            document.getElementById(show).appendChild(img);
        };

    reader = new FileReader();
    // Firefox 3.6, WebKit
    if(reader.addEventListener) { 
        reader.addEventListener('loadend', this.loadEnd, false);
        if (status != null) 
        {
            reader.addEventListener('error', this.loadError, false);
            reader.addEventListener('progress', this.loadProgress, false);
        }

    // Chrome 7
    } else { 
        reader.onloadend = this.loadEnd;
        if (status != null) 
        {
            reader.onerror = this.loadError;
            reader.onprogress = this.loadProgress;
        }
    }
    var preview = new FileReader();
    // Firefox 3.6, WebKit
    if(preview.addEventListener) { 
        preview.addEventListener('loadend', this.previewNow, false);
    // Chrome 7 
    } else { 
        preview.onloadend = this.previewNow;
    }

    // The function that starts reading the file as a binary string
    reader.readAsBinaryString(file);

    // Preview uploaded files
    if (show) {
        preview.readAsDataURL(file);
    }

    // Safari 5 does not support FileReader
    } else {
        xhr = new XMLHttpRequest();
        xhr.open('POST', target+'?up=true', true);
        xhr.setRequestHeader('UP-FILENAME', file.name);
        xhr.setRequestHeader('UP-SIZE', file.size);
        xhr.setRequestHeader('UP-TYPE', file.type);
        xhr.send(file); 

        if (status) {
            document.getElementById(status).innerHTML = 'Loaded : 100%';
        }
        if (show) {
            var newFile  = document.createElement('div');
            newFile.innerHTML = 'Loaded : '+file.name+' size '+file.size+' B';
            document.getElementById(show).appendChild(newFile);
        }   
    }               
};

// Function drop file
this.drop = function(event) {
    event.preventDefault();
    var dt = event.dataTransfer;
    var files = dt.files;
    for (var i = 0; i<files.length; i++) {
        var file = files[i];
        upload(file);
    }
};

// The inclusion of the event listeners (DragOver and drop)

this.uploadPlace =  document.getElementById(place);
this.uploadPlace.addEventListener("dragover", function(开发者_JAVA百科event) {
    event.stopPropagation(); 
    event.preventDefault();
}, true);
this.uploadPlace.addEventListener("drop", this.drop, false); 

}

Thank you.


I spent sometimes this morning in analyzing the same code from html5uploader. With some lucks, I found the root cause.

Change reader = new FileReader(); to var reader = new FileReader(); should solve the issue.

I bet this is because javascripts behaviour of auto-declaring undeclared variable as global variable. This caused the reader variable being reused by all the uploade(file) calls when more than one file is dropped to the browser.

Cheers!

0

精彩评论

暂无评论...
验证码 换一张
取 消