建立基于AJAX样式的文件上传

本文为翻译的,原文忘记了,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">&nbsp; &nbsp;</td>

                        <td id="tdProgress2">&nbsp; &nbsp;</td>

                        <td id="tdProgress3">&nbsp; &nbsp;</td>

                        <td id="tdProgress4">&nbsp; &nbsp;</td>

                        <td id="tdProgress5">&nbsp; &nbsp;</td>

                        <td id="tdProgress6">&nbsp; &nbsp;</td>

                        <td id="tdProgress7">&nbsp; &nbsp;</td>

                        <td id="tdProgress8">&nbsp; &nbsp;</td>

                        <td id="tdProgress9">&nbsp; &nbsp;</td>

                        <td id="tdProgress10">&nbsp; &nbsp;</td>

                    </tr>

                </tbody>

            </table>

        </div>

    </div>

</fieldset>

 

 

正如你所看到的,我使用了一些div来显示或者隐藏上传页面的信息与进度,并且最为重要的是我在iframeonload事件里绑定了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的元素。我们同样添加了对iframebutton提交事件的引用。在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);

}

 

 

你可能已经看到,我们基本的想法是使用timerwindow.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

posted @ 2007-08-03 22:02  启明星工作室  阅读(1666)  评论(1编辑  收藏  举报