`
cuijiemin
  • 浏览: 256312 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

利用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类,并将相应的信息写入该类,最后把该类放入Catch:

if(!IsPostBack)
{
UploadFileInfoufi
=newUploadFileInfo();
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中,加之是一个引用对象,所以对该对象修改后,其它代码访问到的都是最新的值。

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


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

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

ModalDialog


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

小例子


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

利用pool后的代码

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

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

相关推荐

    利用AJAX控制上传文件进度,并生成进度条

    利用AJAX控制上传文件进度,并生成进度条! 同时增加了新的实现方法,详细信息还请使用者自己体会!!

    Ajax + servlet 实现上传进度条显示

    利用Ajax和Servlet实现文件上传,用来commons-fileupload和commons-io两个包。这两个包也在里边。东西做的很简单,但重点是能对这个方法有所了解就行了,有人想做的更炫的可以自行修改。希望能对大家有所帮助。如果...

    Nginx文件上传进度显示

    Nginx上传进度模块。整理成文档了。一般情况下都是采用Ajax异步方式,创建一个iframe,在iframe里面把数据以form方式提交给后端的服务器脚本,由服务器脚本(比如PHP)来负责接收上传的数据。上传迚度可以利用Nginx...

    一个利用AJAX + ASP.NET 2 + C# 实现的带上传进度控制的邮件发送程序代码

    一个利用AJAX + ASP.NET 2 + C# 实现的带上传进度控制的邮件发送程序代码,值得推荐给大家学习邮件发送,ajax技术,Web进度条控制等。

    Ajax原生前端文件(切片)上传附进度后端文件Express源码

    Ajax原生前端文件(切片)上传附进度后端文件Express源码 思路及原理: 1.将大文件切片 ,file是Blob类的实例,利用其slice方法可以将文件切片(HTTP可以多个并发传递(6-7)) 2.同时并发n个切片的上传 ...

    利用DWR实现文件上传进度条

    利用DWR实现文件上传进度条 利用DWR实现文件上传进度条 利用DWR实现文件上传进度条

    MVC中基于Ajax和HTML5实现文件上传功能

    在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能。 基本功能:实现带有进度条的文件上传功能 高级功能:...

    利用jsp+Extjs实现动态显示文件上传进度

    上传一个很大的excel文件到server, server会解析这个excel, 然后一条一条的插入到数据库,整个过程要耗费很长时间,因此当用户点击上传之后,需要显示一个进度条,并且能够根据后台的接收的数据量和处理的进度及时...

    SWFUpload大文件文件上传c#源码(整合flash)

     * 可以显示上传进度;  * 良好的浏览器兼容性;  * 兼容其他JavaScript库 (例如:jQuery, Prototype等);  * 支持Flash 8和Flash 9;  SWFUpload不同于其他基于Flash构建的上传工具,它有着优雅的代码设计,...

    SWFUpload PHP大文件上传

    * 可以显示上传进度; * 良好的浏览器兼容性; * 兼容其他JavaScript库 (例如:jQuery, Prototype等); * 支持Flash 8和Flash 9; SWFUpload不同于其他基于Flash构建的上传工具,它有着优雅的代码设计,开发者...

    AJAX 源码范例

    利用Ajax可以通过使用滑块的滑动来选择所显示的分页,这种拖拽的方式极大提高了用户体验。 源码结构说明 1.Slider文件夹下为源文件 2.Slider.war为部署文件 <br>第22章 程序描述:使用Windows系统...

    AJAX基础概念、核心技术与典型案例(内涵动态实例)

    利用Ajax可以通过使用滑块的滑动来选择所显示的分页,这种拖拽的方式有很好的用户体验。 /test.html 滑动显示分页页面 /js JavaScript脚本文件 /img 系统使用的图片文件夹 第22章(/ch22) ...

    c#描述swfupload上传实例

    * 可以显示上传进度; * 良好的浏览器兼容性; * 兼容其他JavaScript库 (例如:jQuery, Prototype等); * 支持Flash 8和Flash 9; SWFUpload不同于其他基于Flash构建的上传工具,它有着优雅的代码设计,开发者可以...

    swfupload+Struts2多文件上传,有进度条,很漂亮的效果

    * 可以显示上传进度; * 良好的浏览器兼容性; * 兼容其他JavaScript库 (例如:jQuery, Prototype等); * 支持Flash 8和Flash 9; SWFUpload不同于其他基于Flash构建的上传工具,它有着优雅的代码设计,开发者可以...

    SWFUpload 大文件上传 java

    * 可以显示上传进度; * 良好的浏览器兼容性; * 兼容其他JavaScript库 (例如:jQuery, Prototype等); * 支持Flash 8和Flash 9; SWFUpload不同于其他基于Flash构建的上传工具,它有着优雅的代码设计,开发者可以...

    SwfUpload多文件上传演示版源码

     * 可以显示上传进度;  * 良好的浏览器兼容性;  * 兼容其他JavaScript库 (例如:jQuery, Prototype等);  * 支持Flash 8和Flash 9;  SWFUpload不同于其他基于Flash构建的上传工具,它有着优雅的代码设计,...

    UploadSwf批量上传文件

    * 可以显示上传进度; * 良好的浏览器兼容性; * 兼容其他JavaScript库 (例如:jQuery, Prototype等); * 支持Flash 8和Flash 9; SWFUpload不同于其他基于Flash构建的上传工具,它有着优雅的代码设计,开发者可以...

    基于SwfUpload插件的文件批量上传插件GooUploader

    使用了本控件后,在后台编写代码时,不必编写实时监控文件上传进度的复杂代码,只用编写简单的处理保存上传文件的代码即可,因为FLASH插件会自动帮助算出上传进度,并实时定时给控件提供进度显示数据,这样就减轻了...

    PHP利用APC模块实现大文件上传进度条的方法

    查询baidu 、Google ,大体做带进度的上传方式为:flash+php,socket,apc+php等,下面我介绍了apc +php+ajax制作的带进度的上传,并贴出源码,希望对大家有用。 Alternative PHP Cache(APC)是 PHP 的一个免费公开...

    ASP.NET开发实战1200例(第Ⅰ卷)第二十章

    实例528 显示真实上传进度的图片上传功能 (结合jQuery) 798 实例529 仿开心网实现图片在线裁剪(结合 jQuery) 801 20.3 图片存取技术的应用 804 实例530 将上传的相册照片存储到数据库中 804 实例531 读取数据库...

Global site tag (gtag.js) - Google Analytics