本文為翻譯的,原文忘記了,google一下應該找到 呵呵
建立基於AJAX樣式的檔案上傳
如果你訪問ASP.NET AJAX 論壇,你會發現有成百的人詢問當把File控制項放到UpdatePanel裡時,並不能夠產生具有AJAX上傳的效果。這肯定是不能夠產生AJAX效果的,因為XMLHTTPRequest對象在內部上傳資料時不支援這個功能。在本文我將給大家示範一個具有AJAX效果的檔案上傳方式。技巧很簡單,我將使用iframe架構來上傳檔案,這樣就不會重新整理頁面,並且在頁面 上傳過程中,他還會粗略的顯示進度,下面是啟動並執行
下面讓我們詳細介紹一下執行過程。就從main頁面開始吧
<fieldset>
<legend>Photo Upload Demo</legend>
<div id="divFrame">
<iframe id="ifrPhoto" onload="initPhotoUpload()" scrolling="no" frameborder="0" hidefocus="true" style="text-align:center;vertical-align:middle;border-style:none;margin:0px;width:100%;height:55px" src="PhotoUpload.aspx"></iframe>
</div>
<div id="divUploadMessage" style="padding-top:4px;display:none"></div>
<div id="divUploadProgress" style="padding-top:4px;display:none">
<span style="font-size:smaller">Uploading photo...</span>
<div>
<table border="0" cellpadding="0" cellspacing="2" style="width:100%">
<tbody>
<tr>
<td id="tdProgress1"> </td>
<td id="tdProgress2"> </td>
<td id="tdProgress3"> </td>
<td id="tdProgress4"> </td>
<td id="tdProgress5"> </td>
<td id="tdProgress6"> </td>
<td id="tdProgress7"> </td>
<td id="tdProgress8"> </td>
<td id="tdProgress9"> </td>
<td id="tdProgress10"> </td>
</tr>
</tbody>
</table>
</div>
</div>
</fieldset>
正如你所看到的,我使用了一些div來顯示或者隱藏上傳頁面的資訊與進度,並且最為重要的是我在iframe的onload事件裡綁定了initPhotoUpload方法,下面就看看iframe對應頁面的內容
<form id="photoUpload" enctype="multipart/form-data" runat="server">
<div>
<input id="filPhoto" type="file" runat="server"/>
</div>
<div id="divUpload" style="padding-top:4px">
<input id="btnUpload" type="button" value="Upload Photo" />
</div>
</form>The iframe
在iframe頁面裡包含了一個上傳控制項和一個button提交按鈕,現我們看一下initPhotoUpload 函數,他是怎麼執行的
function initPhotoUpload()
{
_divFrame = document.getElementById('divFrame');
_divUploadMessage = document.getElementById('divUploadMessage');
_divUploadProgress = document.getElementById('divUploadProgress');
_ifrPhoto = document.getElementById('ifrPhoto');
var btnUpload = _ifrPhoto.contentWindow.document.getElementById('btnUpload');
btnUpload.onclick = function(event)
{
var filPhoto = _ifrPhoto.contentWindow.document.getElementById('filPhoto');
//Baisic validation for Photo
_divUploadMessage.style.display = 'none';
if (filPhoto.value.length == 0)
{
_divUploadMessage.innerHTML = '<span style=\"color:#ff0000\">Please specify the file.</span>';
_divUploadMessage.style.display = '';
filPhoto.focus();
return;
}
var regExp = /^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))(.jpg|.JPG|.gif|.GIF|.png|.PNG|.bmp|.BMP)$/;
if (!regExp.test(filPhoto.value)) //Somehow the expression does not work in Opera
{
_divUploadMessage.innerHTML = '<span style=\"color:#ff0000\">Invalid file type. Only supports jpg, gif, png and bmp.</span>';
_divUploadMessage.style.display = '';
filPhoto.focus();
return;
}
beginPhotoUploadProgress();
_ifrPhoto.contentWindow.document.getElementById('photoUpload').submit();
_divFrame.style.display = 'none';
}
}
一旦載入iframe架構,我們就執行一些變數,這些變數都是以_為首碼來作為DOM的元素。我們同樣添加了對iframe裡button提交事件的引用。在click事件裡,首先驗證上傳檔案是否為空白,我們還驗證圖片的類型,一段這些驗證通過,我們將調用beginPhotoUploadProgress 方法來處理上傳檔案的過程,下面是beginPhotoUploadProgress
function beginPhotoUploadProgress()
{
_divUploadProgress.style.display = '';
clearPhotoUploadProgress();
_photoUploadProgressTimer = setTimeout(updatePhotoUploadProgress, PROGRESS_INTERVAL);
}
function clearPhotoUploadProgress()
{
for (var i = 1; i <= _maxLoop; i++)
{
document.getElementById('tdProgress' + i).style.backgroundColor = 'transparent';
}
document.getElementById('tdProgress1').style.backgroundColor = PROGRESS_COLOR;
_loopCounter = 1;
}
function updatePhotoUploadProgress()
{
_loopCounter += 1;
if (_loopCounter <= _maxLoop)
{
document.getElementById('tdProgress' + _loopCounter).style.backgroundColor = PROGRESS_COLOR;
}
else
{
clearPhotoUploadProgress();
}
if (_photoUploadProgressTimer)
{
clearTimeout(_photoUploadProgressTimer);
}
_photoUploadProgressTimer = setTimeout(updatePhotoUploadProgress, PROGRESS_INTERVAL);
}
你可能已經看到,我們基本的想法是使用timer(window.setTimeout)來顯示上傳的進度,下載我們看看伺服器的代碼
private const string SCRIPT_TEMPLATE = "<" + "script " + "type=\"text/javascript\">window.parent.photoUploadComplete('{0}', {1});" + "<" + "/script" + ">";
private void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
//Sleeping for 10 seconds, fake delay, You should not it try at home.
System.Threading.Thread.Sleep(10 * 1000);
UploadPhoto();
}
}
private void UploadPhoto()
{
string script = string.Empty;
if ((filPhoto.PostedFile != null) && (filPhoto.PostedFile.ContentLength > 0))
{
if (!IsValidImageFile(filPhoto))
{
script = string.Format(SCRIPT_TEMPLATE, "The uploaded file is not a valid image file.", "true");
}
}
else
{
script = string.Format(SCRIPT_TEMPLATE, "Please specify a valid file.", "true");
}
if (string.IsNullOrEmpty(script))
{
//Uploaded file is valid, now we can do whatever we like to do, copying it file system,
//saving it in db etc.
//Your Logic goes here
script = string.Format(SCRIPT_TEMPLATE, "Photo uploaded.", "false");
}
//Now inject the script which will fire when the page is refreshed.
ClientScript.RegisterStartupScript(this.GetType(), "uploadNotify", script);
}
private static bool IsValidImageFile(HtmlInputFile file)
{
try
{
using (Bitmap bmp = new Bitmap(file.PostedFile.InputStream))
{
return true;
}
}
catch (ArgumentException)
{
//throws exception if not valid image
}
return false;
}
在伺服器上,我們同樣執行了一些基本的驗證,另外還我們還在用戶端產生一些指令碼,這些指令碼將調用main頁面裡的photoUploadComplete 函數,他用來顯示上傳是成功還是失敗
下面是photoUploadComplete 代碼
function photoUploadComplete(message, isError)
{
clearPhotoUploadProgress();
if (_photoUploadProgressTimer)
{
clearTimeout(_photoUploadProgressTimer);
}
_divUploadProgress.style.display = 'none';
_divUploadMessage.style.display = 'none';
_divFrame.style.display = '';
if (message.length)
{
var color = (isError) ? '#ff0000' : '#008000';
_divUploadMessage.innerHTML = '<span style=\"color:' + color + '\;font-weight:bold">' + message + '</span>';
_divUploadMessage.style.display = '';
if (isError)
{
_ifrPhoto.contentWindow.document.getElementById('filPhoto').focus();
}
}
}
該函數很簡單,具體看原始碼吧 code
http://www.cnblogs.com/mqingqing123/archive/2007/08/03/842352.html