因爲業務須要,須要上傳大文件,已有的版本沒法處理IE版本,通過調研,百度的 webuploader 支持 IE 瀏覽器,並且支持計算MD5值,進而能夠實現秒傳的功能。javascript
大文件上傳主要分爲三部分,預上傳,分塊上傳,合併上傳。css
預上傳
:計算MD5值,同時獲取服務器返回的參數,做爲分塊上傳的參數java
分塊上傳
:對文件按照固定的大小進行分塊,分塊後並上傳塊,其中參數包含預上傳計算的MD5值,若是上傳的分塊已經存在,則跳過執行,若是不存在,則執行分塊上傳。web
合併上傳
:當全部的分塊完成上傳後,對文件進行合併上傳。ajax
其中,用到beforeSendFile
,afterFileSend
這兩個監聽函數,其中,監聽函數beforeSendFile,主要是計算MD5值,同時進行預上傳,用到defered,是爲了等待異步執行的結果。uploadBeforeSend與beforeSendFile對應,uploadBeforeSend主要有如下功能:json
默認的上傳參數,能夠擴展此對象來控制上傳參數。promise
能夠擴展此對象來控制上傳頭部。瀏覽器
當某個文件的分塊在發送前觸發,主要用來詢問是否要添加附帶參數,大文件在開起分片上傳的前提下此事件可能會觸發屢次。 afterFileSend 是完成最終的大文件合併上傳。bash
代碼以下:服務器
var fileMd5; //保存文件MD5名稱
var uploader; //全局對象uploader
var dfsId;
var uploadId;
var rnd = GC.gRnd();
var uploadShardSize = parent.gMain.isCeph=="1"?5 * 1024 * 1024:4 * 1024 * 1024;
var discussContent = jQuery('#upload_discusscontent');
if (parent.gMain.diskType == 2) {
discussContent.parent().show();
}
WebUploader.Uploader.register({
"before-send-file" : "beforeSendFile", //文件上傳以前執行
"before-send" : "beforeSend", //文件塊上傳以前執行
"after-send-file" : "afterSendFile", //上傳完成以後執行
},
{
//時間點1:全部進行上傳以前調用此函數
beforeSendFile : function(file) {
console.log(file);
var owner = this.owner
var deferred = WebUploader.Deferred();
// 計算文件的惟一標識,用於斷點續傳和妙傳
(new WebUploader.Uploader()).md5File(file, 0,
10 * 1024 * 1024).progress(
function(percentage) {
jQuery("#" + file.id).find("div.state").text("正在掃描文件") ;
}).then(
function(val) {
fileMd5 = val;
file.fileMd5 = fileMd5
jQuery("#" + file.id).find("div.state").text("成功獲取文件信息");
// 放行
var datas = {
//文件惟一標記
fileMd5 : fileMd5,
diskType: parent.gMain.diskType,
appFileId: '',
creatorUsn: parent.gMain.groupUsn,
uploadType: file.chunks == 1 ? 1 : 3,
comeFrom: 11,
parentId: (parent.gMain.currentFid == -2) ? -1 : parent.gMain.currentFid,
fileSize: file.size,
groupId: parent.gMain.groupId,
fileName: file.name,
discussContent: (parent.gMain.diskType == 2) ? discussContent.val() : '',
model: parent.gMain.uploadModel
};
jQuery.ajax({
type : "POST",
url : parent.gConst.ajaxPostUrl.file + "?func=common:upload&sid="+parent.gMain.sid +"&rnd="+rnd,
data: JSON.stringify(datas),
dataType : "json",
success : function(response) {
console.log(response)
if(response && response.code==='DFS_118'){
owner.skipFile( file );
deferred.reject();
jQuery("#" + file.id).find("div.state").text("秒傳");
} else {
//分塊不存在或不完整,從新發送該分塊內容
dfsId = response.var.dfsFileId;
uploadId = response.var.uploadId;
deferred.resolve();
}
},
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Content-Type", "text/javascript; charset=utf-8");
}
});
});
return deferred.promise();
},
//每個分塊發送以前執行該操做,檢查當前塊是否已經上傳
beforeSend : function(block) {
var deferred = WebUploader.Deferred();
dfsId = dfsId;
deferred.resolve();
this.owner.options.formData = {
fileMd5: fileMd5,
start: block.start
};
return deferred.promise();
},
afterSendFile : function(file) {
// 通知合併分塊
console.log(file)
var comepleteData = {
diskType: parent.gMain.diskType,
uploadType: file.blocks ? file.blocks.length == 1 ? 1 : 3 : 1,
creatorUsn: parent.gMain.groupUsn,
parentId: (parent.gMain.currentFid == -2) ? -1 : parent.gMain.currentFid,
fileSize: file.size,
groupId: parent.gMain.groupId,
fileName: file.name,
fileMd5: fileMd5,
comeFrom: 11,
uploadId: uploadId,
dfsFileId: dfsId,
model: parent.gMain.uploadModel,
partCount: file.blocks ? file.blocks.length : 1
}
jQuery.ajax({
type : "POST",
url : parent.gConst.ajaxPostUrl.file+ "?func=common:completeUpload&sid="+parent.gMain.sid,
data: JSON.stringify(comepleteData),
dataType: 'json',
success : function(response) {
var $li = jQuery('#' + file.id);
$li.find('p.state').text('上傳完成');
jQuery("#ctlBtn").addClass('disabled');
},
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Content-Type", "text/javascript; charset=utf-8");
}
});
}
});
uploader = WebUploader.create({
swf: '../resource_drive/js/control/fileupload/Uploader.swf',
server: 'service/common/onestfile.do?func=common:onestUpload&sid=' + parent.gMain.sid,
pick:{
id: '#asd', //這個id是你要點擊上傳文件按鈕的外層div的id
multiple : true //是否能夠批量上傳,true能夠同時選擇多個文件
},
auto: true,
disableGlobalDnd: true, //禁用頁面拖拽
chunked: true, // 開啓分片上傳
chunkSize: uploadShardSize, //分片大小
chunkRetry: 3, //重傳次數
threads: 1, //同時上傳進程
fileSizeLimit: 2000*1024*1024, //驗證文件總大小
fileSingleSizeLimit: 2000*1024*1024, //驗證單個文件大小
resize: false,
});
//當文件添加進隊列
uploader.on("fileQueued", function(file) {
// fileList
jQuery("#divDialogfileupload").show();
jQuery("#sexwarning").css("display","block");
jQuery(".upfile_ul").css("display","block");
jQuery(".upfile_ul").append("<div id='" + file.id + "'class='fileInfo'><img/><span>" + file.name +
"</span><div class='state'>等待上傳...</div><span class='text'><span></div>");
});
//文件上傳過程當中建立進度條
uploader.on("uploadProgress", function(file, progress){
var id = jQuery("#"+file.id);
id.find("span.text").text((progress.toFixed(2))*100+"%")
id.find("div.state").text("上傳中...")
if (progress == 1) {
id.find("div.state").text("上傳完成")
}
});
//發送前填充數據
uploader.on('uploadBeforeSend', function( block, data ) {
// block爲分塊數據。
console.log(block);
console.log(data);
var deferred = WebUploader.Deferred();
// file爲分塊對應的file對象。
var file = block.file;
var fileMd5 = file.fileMd5;
// 修改data能夠控制發送哪些攜帶數據。
// 將存在file對象中的md5數據攜帶發送過去。
data.appFileId = "";//md5
data.fileMd5 = fileMd5;//md5
data.fileName = data.name;
data.diskType = parent.gMain.diskType;
data.uploadType = block.chunks == 1 ? 1 : 3;
data.creatorUsn = parent.gMain.groupUsn;
data.parentId = (parent.gMain.currentFid == -2) ? -1 : parent.gMain.currentFid;
data.fileSize = data.size;
data.groupId = parent.gMain.groupId;
data.model = parent.gMain.uploadModel;
data.fileRealPath = block.file.source.source.webkitRelativePath;
data.comeFrom = 11;
data.dfsFileId = dfsId;
data.blob = data.name;
if (block.chunks !== 1) {
data.uploadId = uploadId;
data.range = block.start + "-" + block.end;
data.partCount = block.chunks;
data.partNum = block.chunk + 1;
}
data.discussContent = (parent.gMain.diskType == 2) ? discussContent.val() : '';
deferred.resolve();
});
//上傳成功
uploader.on("uploadSuccess", function(file) {
var id = jQuery("#"+file.id);
id.find("div.state").text("已上傳")
});
//上傳失敗
uploader.on('uploadError', function( file ) {
var id = jQuery("#"+file.id);
id.find("div.state").text("上傳失敗")
});
// 上傳完成
uploader.on("uploadComplete", function(file) {
var id = jQuery("#"+file.id);
id.find("div.state").text("上傳完成")
});
複製代碼