cuijiemin 发表于 2013-1-28 20:28:06

利用ajax技术显示上传进度

<span class="Apple-style-span" style="color: rgb(0, 0, 0); font-family: verdana; font-size: 14px; line-height: 21px;">回顾上一篇:

我们介绍了如何从HTTP请求流中将数据部分进行截取,同时将数据相关信息进行保存。

本篇概述:
用过ajax的朋友应该有听过XmlHttpRequest对象,ajax其实就是通过XmlHttpRequest对象来向服务器发出异步请求,并从服务器获得数据,然后用javascript来操作DOM而更新页面。
本篇就是要通过XmlHttpRequest对象来实现实时的进度显示。

效果图:
http://images.cnblogs.com/cnblogs_com/stg609/088041042.JPG
正文部分:
看过有些前辈的做法是通过设置HTTP请求的Refresh头字段来定时刷新页面从而显示进度,但是这样就会带动整个页面一起刷新,就算我们把进度条做成单独的页面,效果仍旧不是太好。我之前试过用ajax的Timer组件,但是不知道是何原因,Timer控件在IIS下预览时总是无法正常发挥作用。苦恼了好一阵子,怀疑是MS的BUG。最后发现了一个很好的替代办法就是利用XmlHttpRequest对象来自己实现定时刷新,这样每次只需向服务器请求很少的数据,减少了对服务器的压力,在后期的测试中,发现这个办法确实很好用,而且在IIS下也一切正常(上图就是IIS下运行的效果)。
当然如果光有进度条没有数据,那这个进度条也只能是个摆设,所以我把接下来的内容分成两块:进度信息的保存、进度的显示

1、进度信息的保存
首先我们要明白进度条在这里反应的是什么的进度?毫无疑问是文件上传的进度喽~~在上一篇中,我们对上传的文件数据进行了提取,也就是说这个提取的进度就是我们要显示给客户端的进度。那就简单了,我们只要把已经提取的文件大小与总的文件大小比对一下,就可以知道完成的百分比了。可是问题来了,我们如何知道上传了多少了呢?答案肯定是要用一个变量来保存已经上传的数据量。那这个变量要放在哪里才能让我们既可以在进度页面中访问,又可以在HTTP上传模块中访问呢?
大家肯定知道一般情况下,用户在多个页面之间访问,会用到Session对象或URL传值来进行页面之前的通信。但是前一篇所介绍的HTTP模块并不属于一个页面,因此我们无法简单的应用Session让进度页面与上传模块实现通信。这里主要还是借鉴高山来客的思路:首先构建一个用于存放文件信息的类,该类主要用来保存文件信息,如:文件名,路径,当前上传的数据量,上传时间等。然后设置一个针对某次上传的唯一ID做为页面中通信的暗号,拥有这个暗号的页面才能获取对应于某次上传的文件信息。现在已经有了两个变量了,接着就要使这两个变量可以被多个页面所使用,方法就是在上传页面中,将这个ID变量注册为该页面的一个隐藏域,这样包含这个页面的HTTP请求流中就会包含那个上传ID。另一个类变量就保存在页面缓存Cache中,并用上传ID做为其编号。
现在假设已经有了这么一个用于存放文件信息的类UploadFileInfo。
首先我们要在上传页面的PageLoad中new一个ID,然后注册一个隐藏域用来保存此ID,同时实例化UploadFileInfo类,并将相应的信息写入该类,最后把该类放入Catch:

<div class="cnblogs_code" style="margin-left: 40px; width: 95%; font-family: verdana; background-color: rgb(238, 238, 238); font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px;">http://www.cnblogs.com/Images/OutliningIndicators/None.gifif(!IsPostBack)
http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif{
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gifUploadFileInfoufi=newUploadFileInfo();
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gifufi.strFileGuid=Guid.NewGuid().ToString;//用GUID来表示唯一的ID;
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gifufi.strTempDir=Server.MapPath("TempUpload/"+ufi.strFileGuid+"//");
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gifClientScript.RegisterHiddenField("UploadID",ufi.strFileGuid);//隐藏域,名字为UploadID,值为ufi.strFileGuid
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gifHttpContext.Current.Cache.Add(ufi.strFileGuid,ufi,null,DateTime.Now.AddDays(10),TimeSpan.Zero,System.Web.Caching.CacheItemPriority.High,null);//加入到Catch中
http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif}
页: [1]
查看完整版本: 利用ajax技术显示上传进度