我需要使用HTML5拖放功能将元素上丢弃的所有文件传输到服务器。 我在下面提供了相应的js代码。我在服务器端有一个servlet来收集文件并将其放在一个文件夹中。如果我在页面上删除1或2个文件,这工作正常。但是,如果我删除4-10个文件,所有文件都在服务器中创建,但多个文件设置为相同的内容,一些文件内容为0K。
你们中的任何人都可以告诉我如何实现正确的行为。 我的要求类似于gmail附件!! 任何能够顺序上传文件的解决方案都非常值得注意。
/*
* 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(event) {
event.stopPropagation();
event.preventDefault();
}, true);
this.uploadPlace.addEventListener("drop", this.drop, false);
}
谢谢。
答案 0 :(得分:2)
我今天早上有时会分析来自html5uploader的相同代码。幸运的是,我找到了根本原因。
将reader = new FileReader();
更改为var reader = new FileReader();
可以解决问题。
我敢打赌这是因为javascripts自动声明未声明的变量作为全局变量的行为。当多个文件被删除到浏览器时,这会导致所有reader
调用重用uploade(file)
变量。
干杯!