我正在尝试使用FileReader API将文件上传到服务器。
文件上传效果很好。虽然我是以块的形式上传文件,但是在上传后没有释放FormData对象使用的内存,即上传大文件会导致浏览器崩溃。
这是我的代码: 我想知道我做错了什么?
function uid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
function parseFile(file) {
var fileSize = file.size;
var chunkSize = 10 * 1024 * 1024; // bytes
var offset = 0;
var block = null;
var doUpload = null;
var sendEndSignal = null;
var id = uid();
var chunks = {};
var r = new FileReader();
var xhr = new XMLHttpRequest();
var fd = new FormData();
var foo = function (evt) {
}
block = function (_offset, length, _file) {
var blob = _file.slice(_offset, length + _offset);
r.onload = foo;
r.onloadend = (
function (file, id, off) {
return function (evt) {
if (evt.target.error == null) {
off += chunkSize;
if (off >= fileSize) {
console.log("Done reading file");
return;
}
var fnc = block;
doUpload(file, evt.target.result, id, Math.floor(off / chunkSize), chunks, chunkSize, block, off);
} else {
alert("Read error: " + evt.target.error);
return;
}
}
})(_file, id, _offset);
r.readAsDataURL(blob);
}
doUpload = function (file, data, id, chunk, chunks, chunkSize,nx,off) {
xhr = new XMLHttpRequest();
fd = new FormData();
fd.append(file.name + "-----" + id + "-----" + String(chunk), data);
xhr.open("post", "Handler1.ashx", true);
xhr.send(fd);
xhr.addEventListener('readystatechange',
function (e) {
if (this.readyState === 4) {
chunks[Math.floor(chunk)] = 1;
var cnt = 0;
var cntDone = 0;
for (var key in chunks) {
if (chunks.hasOwnProperty(key)) {
cnt++;
if (chunks[key] === 1)
cntDone += 1;
}
}
if (nx)
nx(off,chunkSize,file);
if (cnt === Math.ceil(file.size / chunkSize) && cnt === cntDone)
sendEndSignal(file, id, cnt - 1);
}
});
}
sendEndSignal = function (file, id, num) {
fd = new FormData();
xhr = new XMLHttpRequest();
fd.append("Done-----" + file.name + "-----" + id, num);
xhr.open("post", "Handler1.ashx", true);
xhr.send(fd);
}
block(offset, chunkSize, file);
}
谢谢。
更新 我使用jquery post而不是XMLHttpRequest和FormData解决了我的问题。 这就是我所做的:
<script type="text/javascript">
function uid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
function parseFile(file,index) {
var fileSize = file.size;
var chunkSize = 10 * 1024 * 1024; // bytes
var offset = 0;
var block = null;
var doUpload = null;
var sendEndSignal = null;
var id = uid();
var chunks = {};
var r = new FileReader();
var foo = function (evt) {
}
block = function (_offset, length, _file) {
var blob = _file.slice(_offset, length + _offset);
var div = document.getElementById("file-" + String(index));
div.innerHTML = div.innerHTML + "*";
r.onload = foo;
r.onloadend = (
function (file, id, off) {
return function (evt) {
if (evt.target.error == null) {
doUpload(file, evt.target.result, id, Math.floor(off / chunkSize), chunks, chunkSize, block, off,index);
} else {
alert("Read error: " + evt.target.error);
return;
}
}
})(_file, id, _offset);
r.readAsDataURL(blob);
}
doUpload = function (file, data, id, chunk, chunks, chunkSize, nx, off,ind) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "WebForm1.aspx/ProcessData",
data: "{'data':'" + data + "','name':'" + file.name + "-----" + id + "-----" + String(chunk) + "'}",
success: function (dd) {
debugger;
chunks[Math.floor(chunk)] = 1;
var cnt = 0;
var cntDone = 0;
for (var key in chunks) {
if (chunks.hasOwnProperty(key)) {
cnt++;
if (chunks[key] === 1)
cntDone += 1;
}
}
if (cnt === Math.ceil(file.size / chunkSize) && cnt === cntDone)
sendEndSignal(file, id, cnt - 1,ind);
if (nx) {
debugger;
off += chunkSize;
if (off >= file.size) {
return;
}
nx(off, chunkSize, file);
}
},
error: function (result) {
alert(JSON.stringify(result));
}
});
}
sendEndSignal = function (file, id, num,ind) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "WebForm1.aspx/ProcessData",
data: "{'data':'" + num + "','name':'" + "Done-----" + file.name + "-----" + id + "'}",
success: function (dd) {
var div = document.getElementById("file-" + String(ind));
div.innerHTML = "<b>" + file.name + "</b> => DONE!!!!";
},
error: function (result) {
alert(JSON.stringify(result));
}
});
}
block(offset, chunkSize, file);
}
function xx(inp) {
var i = 0;
var file;
var node = document.getElementById("dupl");
debugger;
while (node.hasChildNodes())
node.removeChild(node.lastChild);
for (i = 0; i < inp.files.length; i++) {
file = inp.files[i];
var dd = document.createElement("div");
dd.id = "file-" + String(i);
dd.innerHTML = "<b>" + file.name + "</b>";
document.getElementById("dupl").appendChild(dd);
}
for (i = 0; i < inp.files.length; i++) {
file = inp.files[i];
parseFile(file,i);
}
}
</script>
希望这对某人有用。