Asp.Net 上传大文件专题(4)--利用ajax技术显示上传进度

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

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

       效果图:


      正文部分:
      看过有些前辈的做法是通过设置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类,并将相应的信息写入该类,最后把该类放入Cache:
      

复制代码
if  ( ! IsPostBack)
ExpandedBlockStart.gif
{
    UploadFileInfo ufi 
= new UploadFileInfo();
    ufi.strFileGuid 
= Guid.NewGuid().ToString;//用GUID来表示唯一的ID;
    ufi.strTempDir 
= Server.MapPath("TempUpload/" + ufi.strFileGuid + "//");
    ClientScript.RegisterHiddenField(
"UploadID", ufi.strFileGuid);//隐藏域,名字为UploadID,值为ufi.strFileGuid
    HttpContext.Current.Cache.Add(ufi.strFileGuid, ufi, null, DateTime.Now.AddDays(10), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, null);//加入到Catch中
}
复制代码


      经过以上步骤,我们就可以在HTTP模块中访问了。
      因为在这次的HTTP请求流中包含了一个隐藏域,所以我们可以对获取的HTTP请求流进行分析,从而获取相应的上传ID,也就是我们之前说的暗号。然后通过Cache的编号找到Cache中的文件信息对象,从而我们可以在后来的数据读取过程中对该对象的上传数据量进行修改。由于是放在Cache中,加之是一个引用对象,所以对该对象修改后,其它代码访问到的都是最新的值。

string  sguid  =  GetUploadId(bPreloadedEnitityBody, eContentEncode); // GetUploadId是自己写的一个方法用来从请求流中获取上传ID
UploadFileInfo ufiFileInfo  =  (UploadFileInfo)HttpContext.Current.Cache[sguid]; // 取出文件信息对象


      其它页面如果要使用这个对象就得先获取ID,之后就可以自由操作了。

      2、进度的显示
      从图中我们可以看到,当显示进度的时候,背后的页面成灰色,并且无法响应任何事件,有点类似模态窗口。这个效果大家可以在网上查查,还是挺容易实现的。我这里有一段js显示此效果的代码(搜集于网上):

ContractedBlock.gif ModalDialog


      接着讲我们的重点:如何实现定时局部刷新。
      关于XmlHttpRequest对象,我这里就不详细讲述了,提供大家一个关于此的手册下载。为了大家更容易理解,我举个小例子:
  

ContractedBlock.gif 小例子

    

      通过以上小例子,大家应该已经对该对象有所了解了吧。为实现定时刷新,我把进度条单独放在一个页面中(如A.aspx),通过js的setTimeout来定时执行类似returnresponse这样的方法,然后在A.aspx.cs代码中获取文件信息对象,接着通过Response来反馈进度信息。这样在A.aspx页面中就可以获取到信息,并进行显示了。但是执行ActiveXObject将要花费不少代价,而且我们是定时执行该方法,显然会造成性能下降。在参考了构建一个pool来管理无刷新页面的xmlhttp对象后,决定采用这一方法,事实证明该方法确实有效。

ContractedBlock.gif 利用pool后的代码

       到这就差不多整个专题都结束了,接下来几天,我会把代码稍微调整下,然后传上来。 

       由于这段时间要上班,实在抽不出时间来整理,如果大家需要可以先拿去看看。不过代码写的有点乱,而且有些功能也没有完善,时间实在太少,大家见谅。

       粗糙的工程








本文转自stg609博客园博客,原文链接:http://www.cnblogs.com/stg609/archive/2008/08/04/1259469.html,如需转载请自行联系原作者

目录
相关文章
|
26天前
|
XML 前端开发 JavaScript
AJAX 前端开发利器:实现网页动态更新的核心技术
**AJAX** 允许网页在不刷新的情况下更新内容,实现异步与服务器交换数据。通过JavaScript的XMLHttpRequest对象,可发送和接收数据。当用户触发事件(如点击),函数向服务器发送GET请求,服务器响应后更新指定HTML部分。AJAX并非编程语言,而是利用浏览器内置对象、JavaScript和DOM技术。核心是XMLHttpRequest对象,它有多种方法(如`open()`和`send()`)和属性(如`onreadystatechange`、`readyState`和`status`)来处理请求和响应。
52 2
AJAX 前端开发利器:实现网页动态更新的核心技术
|
2月前
|
设计模式 前端开发 JavaScript
Ajax技术【Ajax 实战】(二)-全面详解(学习总结---从入门到深化)
Ajax技术【Ajax 实战】(二)-全面详解(学习总结---从入门到深化)
22 0
|
2月前
|
XML JSON 前端开发
JavaWeb----Ajax技术
JavaWeb----Ajax技术
57 0
|
3月前
|
前端开发 JavaScript API
Ajax技术的秘密揭秘:异步传输,高效交互
Ajax技术的秘密揭秘:异步传输,高效交互
|
3月前
|
XML JSON 前端开发
Ajax技术【Ajax技术详解、 Ajax 的使用、Ajax请求、 JSON详解、JACKSON 的使用 】(一)-全面详解(学习总结---从入门到深化)
Ajax技术【Ajax技术详解、 Ajax 的使用、Ajax请求、 JSON详解、JACKSON 的使用 】(一)-全面详解(学习总结---从入门到深化)
58 1
|
1月前
|
XML 开发框架 .NET
C# .NET面试系列八:ADO.NET、XML、HTTP、AJAX、WebService
## 第二部分:ADO.NET、XML、HTTP、AJAX、WebService #### 1. .NET 和 C# 有什么区别? .NET(通用语言运行时): ```c# 定义:.NET 是一个软件开发框架,提供了一个通用的运行时环境,用于在不同的编程语言中执行代码。 作用:它为多语言支持提供了一个统一的平台,允许不同的语言共享类库和其他资源。.NET 包括 Common Language Runtime (CLR)、基础类库(BCL)和其他工具。 ``` C#(C Sharp): ```c# 定义: C# 是一种由微软设计的面向对象的编程语言,专门为.NET 平台开发而创建。 作
173 2
|
3月前
|
JSON 前端开发 JavaScript
探秘 AJAX:让网页变得更智能的异步技术(下)
探秘 AJAX:让网页变得更智能的异步技术(下)
探秘 AJAX:让网页变得更智能的异步技术(下)
|
3月前
|
XML 前端开发 JavaScript
探秘 AJAX:让网页变得更智能的异步技术(上)
探秘 AJAX:让网页变得更智能的异步技术(上)
探秘 AJAX:让网页变得更智能的异步技术(上)
|
3月前
|
设计模式 缓存 前端开发
Ajax技术【Ajax 实战】(二)-全面详解(学习总结---从入门到深化)(下)
Ajax技术【Ajax 实战】(二)-全面详解(学习总结---从入门到深化)
15 1
|
3月前
|
前端开发 JavaScript fastjson
Ajax技术【Ajax 实战】(二)-全面详解(学习总结---从入门到深化)(上)
Ajax技术【Ajax 实战】(二)-全面详解(学习总结---从入门到深化)
24 1