Tuesday, April 10, 2012

Ajax 多檔案上傳套件 Uploadify

最近在開發一個檔案共享的系統 使用者可以透過單一的站台

把檔案上傳到指定的檔案伺服器 系統會發出信件給想分享的人

信中會有下載連結以及檔案的概略描述

採用的是一個可以一次選擇多個檔案的上傳套件 - Uploadify

免費而且功能強大



頁面上所需要的主要控制項

<input id="uploadify" type="file"/>
<input type="button" value="開始傳送" id="start"/>
<input type="button" value="清除" id="clear"/>
<div id="status-message"></div>
<div id="fileQueue"></div>

主要的script如下

$('#uploadify').uploadify({
'uploader': './js/uploadify/uploadify.swf',
'script': './UploadHandler.ashx?Des=' + $('#FSList').find(":selected").val(), //處理上傳動作的檔案
'cancelImg': './js/uploadify/cancel.png',
'folder': $('#guid').val(),//取GUID當作FolderName
'queueID': 'fileQueue',
'sizeLimit': $('#hFileSize').val(), //容量上限(KB)
'auto': false, //選擇檔案後自動上傳
'multi': true, //多檔案上傳
'removeCompleted': false, //上傳完成後,true為自動刪除隊列
'fileDesc': $('#hFileDesc').val(), //可上傳的副檔名提示訊息
'fileExt': $('#hFileExt').val(), //可上傳的副檔名
'queueSizeLimit': 5, //可選取的檔案數量
'onSelectOnce': //選擇檔案
function (event, data) {
//$('#status-message').text(data.filesSelected + ' Files Add To List');
},
'onCancel': //取消單一檔案
function (event, ID, fileObj, data) {

},
'onComplete': //完成單一檔案上傳
function (event, ID, fileObj, response, data) {
$.ajax({
type: 'POST',
url: 'WebService.asmx/MultiUpload',
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: "{ GroupID : '" + $('#guid').val() +
"' , FileName : '" + fileObj.name +
"' , FileSize : '" + fileObj.size +
"' , Site : '" + $('#site').val() +
"' , FilePath : '" + fileObj.filePath +
"' , FileType : '" + fileObj.type +
"' , Speed : '" + data.speed +
"' , Creator : '" + $('#who').val() + "' }",
success: function (oXml) {

},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
},
'onAllComplete': //完成所有檔案上傳
function (event, data) {
$('#loading').hide();//隱藏正在傳輸中的字樣
$('#status-message').html(' Files Upload Complete : '+ data.filesUploaded
+ ' Files Error : ' + data.errors
+ ' Total Size : ' + data.allBytesLoaded
+ ' Average Speed : ' + data.speed + ' kb/s');
var receiver = $('#receiver').val().replace("\\", "");

$.ajax({
type: 'POST',
url: 'WebService.asmx/UploadComplete',
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: "{ GroupID : '" + $('#guid').val() +
"' , TotalSize : '" + data.allBytesLoaded +
"' , AvgSpeed : '" + data.speed +
"' , MailTo : '" + receiver +
"' , Description : '" + $('#filecontent').val().replace("\\", "") +
"' , Creator : '" + $('#who').val() + "' }",
success: function (oXml) {
alert('上傳完成');
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
$('#guid').val($(this).GUID());
//傳輸完成後更換GUID以利區別
$('#uploadify').uploadifySettings('folder', $('#guid').val());
}, //所有文件上傳完成後觸發
'onError': //發生錯誤
function (event, ID, fileObj, errorObj) {
alert(errorObj.type + ' Error: ' + errorObj.info);
}
});
$('#clear').click(function () {
$('#uploadify').uploadifyClearQueue();
$('#status-message,#receiver,#filecontent').empty(); //清除資訊
});
$('#start').click(function () {
$('#loading').show();//顯示正在傳輸中的字樣
$('#uploadify').uploadifyUpload();//觸發上傳的動作
});
$('#FSList').change(function () {
$('#uploadify').uploadifySettings('script', './UploadHandler.ashx?Des=' + $(this).find(":selected").val());//使用者更換目的地
$('#site').val($(this).find(":selected").val());//儲存目的地在hidden欄位
});

在單一檔案完成以及全部檔案完成的時候

會利用JQuery呼叫WebService將相關資訊寫入資料庫

以利稽核

要另外建立一個泛型處理常式(ashx)來處理檔案寫入的部分

context.Response.ContentType = "text/plain";
//由於uploadify的flash是採用utf-8的編碼方式,所以上傳頁面也要用utf-8編碼,才能正常上傳中文檔名的文件
context.Request.ContentEncoding = Encoding.GetEncoding("UTF-8");
context.Response.ContentEncoding = Encoding.GetEncoding("UTF-8");
context.Response.Charset = "UTF-8";
HttpPostedFile folder = context.Request.Files["Filedata"];
int Count = ConfigurationManager.AppSettings["AvailableCount"].ToSafeInt();
string Site = string.Empty;
for (int i = 1; i <= Count; i++)
{
string strName = ConfigurationManager.AppSettings["FileServerName_" + i.ToSafeString()].ToSafeString();
if (strName == context.Request.QueryString["Des"].ToSafeString())
{
Site = ConfigurationManager.AppSettings[strName].ToSafeString();
}
}
string uploadPath = Site + context.Request["folder"] + @"\";
if (folder != null)
{
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
folder.SaveAs(uploadPath + folder.FileName);
//下面這句代碼缺少的話,無法正常運作
context.Response.Write("1");
}
else
{
context.Response.Write("-1");
}

如果要直接寫入IIS本機的話 可以直接給D:\Sobi 這樣的路徑

或是可以給這樣的路徑\\10.1.2.34\Sobi

要先開好共享並且設定權限

Web.config 設定

<identity impersonate="true" userName="Sobi" password="p@ssw0rd"/><!--上傳的帳號密碼-->
<httpRuntime executionTimeout="36000" maxRequestLength="512000"/><!--將檔案上傳限制設定在500MB-->

以II7為例 預設的上傳限制為30MB
要修改的話打開 %windir%\system32\inetsrv\config\applicationhost.config
找到<requestFiltering>
在tag內新增 <requestLimits maxAllowedContentLength="2147483647" />
單位:Byte 此例為2GB

此套件的過濾上傳副檔名是用白名單的方式

只是在選取的時候隱藏未被加入的

但是如果使用者直接輸入檔名 還是可以上傳

No comments:

Post a Comment