尝试克服Flash上传到服务器功能的可变缺陷 - 特别是在需要cookie时无法跟踪上传进度 - 我决定创建一个JavaScript函数来执行上传并跟踪上传进度事件。
这是:
window.you_animate = {
objToString: function(obj) {
var res = "{";
for (var str in obj) {
res += str +"=" + obj[str] + ",";
}
res += "}";
return res;
},
upload: function(url, _files, _data, progressCb, successCb, errorCb) {
alert("a,"+url);
var fd = new FormData(),
files = _files || [],
data = _data || [],
i;
alert("b");
for (i in data) {
fd.append(i, data[i]);
}
alert("c");
for (i = 0; i < files.length; i++) {
var file = files[i];
alert(i+"/"+files.length+" file= "+you_animate.objToString(file));
var blob = file.file || new Blob(file.data, {
type: file.type
});
alert("blob= "+you_animate.objToString(blob));
fd.append(file.name, blob);
}
alert("d");
var ajax_opts = {
type: 'POST',
url: url,
data: fd,
headers: {},
dataType: 'json',
contentType: false,
processData: false,
xhr: function() {
alert("1");
var xhr = new window.XMLHttpRequest();
if (xhr.upload) {
xhr.upload.addEventListener('progress', progressCb, false);
}
return xhr;
},
success: successCb || $.noop,
error: errorCb || $.noop
};
alert("2");
$.ajax(ajax_opts);
alert("3");
},
uploadProgress: {},
// => _data = base64 binary
uploadFromFlash: function(url, _files, _data) {
alert("0");
var uploadProcess = {};
var uploadProcessID = "id" + Math.floor(Math.random() * 1000000).toString();
you_animate.uploadProgress[uploadProcessID] = uploadProcess;
// workaround for Flash bug ("[]" in variable name)
for (var str in _data) {
_data["UploadCharacterForm["+str+"]"] = _data[str];
delete _data[str];
}
alert("01");
// base64 -> Blob-friendly stuff
for (i = 0; i < _files.length; i++) {
var file = _files[i];
var binary = atob(file.data);
var array = new Uint8Array(binary.length);
for( var i = 0; i < binary.length; ++i ) { array[i] = binary.charCodeAt(i) }
file.data = [array]; // NOTE : why "[array]" and not "array" ??
}
alert("02");
you_animate.upload(url, _files, _data,
function(progressEvent) {
uploadProcess.progressEvent = progressEvent;
},
function(successEvent) {
uploadProcess.successEvent = successEvent;
uploadProcess = null;
},
function(errorEvent) {
uploadProcess.errorEvent = errorEvent;
uploadProcess = null;
}
);
return uploadProcessID;
},
trackProcessID: function(id) {
return you_animate.uploadProgress[id];
},
destroyProcessID: function(id) {
delete you_animate.uploadProgress[id];
},
uploadForm: function(form, progressCb, successCb, errorCb) {
var $form = $(form),
action = $form.attr('action') + '?json';
var data = $form.serializeArray().reduce(function(prev, curr){
prev[curr.name] = curr.value; return prev;
}, {} );
var $files = $form.find('input[type=file]');
var files = [];
$files.each(function(index, node) {
if (node.files[0]) {
files.push({
name: node.name,
file: node.files[0]
});
}
});
you_animate.upload(action, files, data, progressCb, successCb, errorCb);
}
};
问题1 : Chrome和Firefox 之间的进度事件有所不同。第一个返回loaded
&amp; totalSize
(在许多其他内容中),而Firefox返回loaded
&amp; total
!!!
是否存在返回进度事件的规范?!
问题2 :Internet Explorer 8在警报后立即崩溃(&#34; 0&#34;)!也许它不喜欢&#34; []&#34;在以下行中:
_data["UploadCharacterForm["+str+"]"] = _data[str];
有什么关系吗?