杭州设计公司,杭州广告设计公司
网页设计
asp网页进度条
信息来源:未知     栏目类别: 网页设计     浏览次数:     发表评论 减小字体 增大字体
1.Asp无组件上传进度条
一、无组件上传的原理
我还是一点一点用一个实例来说明的吧,客户端HTML如下。要浏览上传附件,我们通过<i**put type="file">元素,但是一定要注意必须设置form的e**ctype属性为"multipart/form-data":


<form method="post" actio**="upload.asp" e**ctype="multipart/form-data">
<label>
<i**put type="file" **ame="file1" />
</label>
<br />
<i**put type="text" **ame="file**ame" value="default file**ame"/>
<br />
<i**put type="submit" value="Submit"/>
<i**put type="reset" value="Reset"/>
</form>


在后台asp程序中,以前获取表单提交的ASCII 数据,非常的容易。但是如果需要获取上传的文件,就必须使用Request对象的Bi**aryRead方法来读取。Bi**aryRead方法是对当前输入流进行指定字节数的二进制读取,有点需要注意的是,一旦使用Bi**aryRead 方法后,再也不能使用Request.Form 或 Request.QueryStri**g 集合了。结合Request对象的TotalBytes属性,可以将所有表单提交的数据全部变成二进制,不过这些数据都是经过编码的。首先让我们来看看这些数据是如何编码的,有无什么规律可循,编段代码,在代码中我们将Bi**aryRead读取的二进制转化为文本,输出出来,在后台的upload.asp中(注意该示例不要上传大文件,否则可能会造成浏览器死掉):
<%
Dim biData, PostData
Size = Request.TotalBytes
biData = Request.Bi**aryRead(Size)
PostData = Bi**aryToStri**g(biData,Size)
Respo**se.Write "<pre>" & PostData & "</pre>" '使用pre,原样输出格式
' 借助RecordSet将二进制流转化成文本
Fu**ctio** Bi**aryToStri**g(biData,Size)
Co**st adLo**gVarChar = 201
Set RS = CreateObject("ADODB.Recordset")
RS.Fields.Appe**d "mBi**ary", adLo**gVarChar, Size
RS.Ope**
RS.AddNew
RS("mBi**ary").Appe**dChu**k(biData)
RS.Update
Bi**aryToStri**g = RS("mBi**ary").Value
RS.Close
E**d Fu**ctio**
%>


简单起见,上传一个最简单的文本文件(G:\homepage.txt,内容为"宝玉:http://www.webuc.**et")来试验一下,文本框file**ame中保留默认值"default file**ame",提交看看输出结果:

-----------------------------7d429871607fe
Co**te**t-Dispositio**: form-data; **ame="file1"; file**ame="G:\homepage.txt"
Co**te**t-Type: text/plai**
宝玉:http://www.webuc.**et
-----------------------------7d429871607fe
Co**te**t-Dispositio**: form-data; **ame="file**ame"
default file**ame
-----------------------------7d429871607fe--

可以看出来对于表单中的项目,是用过"-----------------------------7d429871607fe"这样的边界来分隔成一块一块的,每一块的开始都有一些描述信息,例如:Co**te**t-Dispositio**: form-data; **ame="file**ame",在描述信息中,通过**ame="file**ame"可以知道表单项的**ame。如果有file**ame="G:\homepage.txt"这样的内容,说明是一个上传的文件,如果是一个上传的文件,那么描述信息会多一行Co**te**t-Type: text/plai**来描述文件的Co**te**t-Type。描述信息和主体信息之间是通过换行来分隔的。

嗯,基本上清晰了,根据这个规律我们就知道该怎么来分离数据,再对分离的数据进行处理了,不过差点忽略一个问题,就是边界值(上例中的"-----------------------------7d429871607fe")是怎么知道的?每次上传这个边界值是不一样的,还好还好asp中可以通过Request.ServerVariables( "HTTP_CONTENT_TYPE")来获之,例如上例中HTTP_CONTENT_TYPE内容为:"multipart/form-data; bou**dary=---------------------------7d429871607fe",有了这个,我们不仅可以判断客户端的form中有无使用e**ctype="multipart/form-data"(如果没有使用,那么下面就没必要执行啦),还可以获取边界值bou**dary=---------------------------7d429871607fe。(注意:这里获取的边界值比上面的边界值开头要少"--",最好补充上。)

至于如何分析数据的过程我就不多赘述了,无非就是借助I**Str,Mid等这样的函数来分离出来我们想要的数据。

二、分块上传,记录进度
要实时反映进度条,实质就是要实时知道当前服务器获取了多少数据?再回想一下我们实现上传的过程,我们是通过Request.Bi**aryRead(Request.TotalBytes)来实现的,在Request的过程中我们无法得知当前服务器获取了多少数据。所以只能通过变通的方法了,如果我们可以将获取的数据分成一块一块的,然后根据已经上传的块数我们就可以算出来当前上传了多大了!也就是说,如果我1K为1块,那么上传1MB的输入流就分成1024块来获取,例如我当前已经获取了100块,那么就表明当前上传了100K。当我提出分块的时候很多人觉得不可思议,因为他们都忽略Bi**aryRead方法不仅是可以读取指定大小,而且可以连续读取的。

写个例子来验证一下分块读取的完整性,在刚才的例子基础上(注意该示例不要上传大文件,否则可能会造成浏览器死掉):

<%
Dim biData, PostData, TotalBytes, Chu**kBytes
Chu**kBytes = 1 * 1024 ' 分块大小为1K
TotalBytes = Request.TotalBytes ' 总大小
PostData = "" ' 转化为文本类型后的数据
ReadedBytes = 0 ' 初始化为0
' 分块读取
Do While ReadedBytes < TotalBytes
biData = Request.Bi**aryRead(Chu**kBytes) ' 当前块
PostData = PostData & Bi**aryToStri**g(biData,Chu**kBytes) ' 将当前块转化为文本并拼接
ReadedBytes = ReadedBytes + Chu**kBytes ' 记录已读大小
If ReadedBytes > TotalBytes The** ReadedBytes = TotalBytes
Loop
Respo**se.Write "<pre>" & PostData & "</pre>" ' 使用pre,原样输出格式
' 将二进制流转化成文本
Fu**ctio** Bi**aryToStri**g(biData,Size)
Co**st adLo**gVarChar = 201
Set RS = CreateObject("ADODB.Recordset")
RS.Fields.Appe**d "mBi**ary", adLo**gVarChar, Size
RS.Ope**
RS.AddNew
RS("mBi**ary").Appe**dChu**k(biData)
RS.Update
Bi**aryToStri**g = RS("mBi**ary").Value
RS.Close
E**d Fu**ctio**
%>

试验一下上传刚才的文本文件,输出结果证明这样分块读取的内容是完整的,并且在While循环中,我们可以在每次循环时将当前状态记录到Applicatio**中,然后我们就可以通过访问该Applicatio**动态获取上传进度条。

另:上例中是通过字符串拼接的,如果是要拼接二进制数据,可以通过ADODB.Stream对象的Write方法,示例代码如下:

Set bSourceData = createobject("ADODB.Stream")
bSourceData.Ope**
bSourceData.Type = 1 'Bi**ary
Do While ReadedBytes < TotalBytes
biData = Request.Bi**aryRead(Chu**kBytes)
bSourceData.Write biData ' 直接使用write方法将当前文件流写入bSourceData中
ReadedBytes = ReadedBytes + Chu**kBytes
If ReadedBytes > TotalBytes The** ReadedBytes = TotalBytes
Applicatio**("ReadedBytes") = ReadedBytes
Loop


三、保存上传的文件
通过Request.Bi**aryRead获取提交数据,分离出上传文件后,根据数据类型的不同,保存方式也不同:

对于二进制数据,可以直接通过ADODB.Stream对象的SaveToFile方法,将二进制流保存成为文件。
对于文本数据,可以通过TextStream对象的Write方法,将文本数据保存到文件中。
对于文本数据和二进制数据,是可以方便的相互转换的,对于上传小文件来说,两者基本上没什么差别。但是两种方式保存时还是有一些差别的,对于ADODB.Stream对象,必须将所有数据全部装载完才可以保存成文件,所以使用这种方式如果上传大文件将很占用内存,而对于TextStream对象,可以在文件创建好后,一次Write一部分,分多次Write,这样的好处是不会占用服务器内存空间,结合上面分析的分块获取数据原理,我们可以每获取一块上传数据就将之Write到文件中。我曾做过试验,同样本机上传一个200多MB的文件,使用第一种方式内存一直在涨,到最后直接提示计算机虚拟内存不足,最可恨是即使进度条表示文件已经上传完,但是最终文件还是没有保存上。而使用后一种方法,上传过程中内存基本上无什么变化。

四、未解决的难题
我在博客园上看到Bestcomy描述他的Asp.Net上传组件是可以和Sever.SetTimeOut无关的,而在Asp中我是没能做到,对于上传大文件,就只有将Server.SetTimeOut设置为一个很大的值才可以。不知道有没有比较好的解决方法。

如果在保存文件时,使用TextStream对象的Write方法,那么如果用户上传时中断了文件传输,已经上传的那部分文件还是在的,如果可以断点续传就好了。关键问题是Request.Bi**aryRead方法虽然可以分块读取,但是却不能跳过某一段读取!


2.一个进度条,大致的思想是
在后台处理数据时,前台页面同时计数显示proess bar
使用了layer来显示
用法:
1。引用
<script la**guage="javascript" alt=" asp进度条 " src=http://www.yeahtech.com/study/showprocessbar.js></script>
2。在提交butto**或<a>或<spa**> 加扩展属性
isshowprocessbar="true"


文件showprocessbar.js如下

addprocessbar();
var bwidth=0;
var swidth = docume**t.all.waiti**g.clie**twidth;

fu**ctio** checkisprocessbar(obj)
{
if (obj.isshowprocessbar=="true")
{
retur** false;
}
else
{
retur** true;
}
}

fu**ctio** checkclick(e)
{
if (e == 1)
{
if (bwidth<swidth*0.98){
bwidth += (swidth - bwidth) * 0.025;
if (docume**t.all)docume**t.sbar.width = bwidth;
else docume**t.rati**g.clip.width = bwidth;
settimeout('checkclick(1);',150);

}
}
else
{
if(docume**t.all)
{
if(docume**t.all.waiti**g.style.visibility == 'visible')
{docume**t.all.waiti**g.style.visibility = 'hidde**';
bwidth = 1;}
whichit = eve**t.srceleme**t;

while (checkisprocessbar(whichit))
{
whichit = whichit.pare**teleme**t;
if (whichit == **ull)retur** true;
}


docume**t.all.waiti**g.style.pixeltop = (docume**t.body.offsetheight - docume**t.all.waiti**g.clie**theight) / 2 + docume**t.body.scrolltop;
docume**t.all.waiti**g.style.pixelleft = (docume**t.body.offsetwidth - docume**t.all.waiti**g.clie**twidth) / 2 + docume**t.body.scrollleft;
docume**t.all.waiti**g.style.visibility = 'visible';
if(!bwidth)checkclick(1);
bwidth = 1;

}

else
{

if(docume**t.waiti**g.visibility == 'show')
{docume**t.waiti**g.visibility = 'hide';
docume**t.rati**g.visibility = 'hide';
bwidth = 1;}
if(e.target.href.tostri**g() != ')
{
docume**t.waiti**g.top = (wi**dow.i****erheight - docume**t.waiti**g.clip.height) / 2 + self.pageyoffset;
docume**t.waiti**g.left = (wi**dow.i****erwidth - docume**t.waiti**g.clip.width) / 2 + self.pagexoffset;
docume**t.waiti**g.visibility = 'show';
docume**t.rati**g.top = (wi**dow.i****erheight - docume**t.waiti**g.clip.height) / 2 + self.pageyoffset+docume**t.waiti**g.clip.height-10;
docume**t.rati**g.left = (wi**dow.i****erwidth - docume**t.waiti**g.clip.width) / 2 + self.pagexoffset;
docume**t.rati**g.visibility = 'show';
if(!bwidth)checkclick(1);
bwidth = 1;
}
}
retur** true;
}
}

fu**ctio** addprocessbar()
{

var str=""
str+= "<div id=waiti**g style=positio**:absolute;top:50px;left:100px;z-i**dex:1;visibility:hidde** >";
str+= "<layer **ame=waiti**g visibility=visible zi**dex=2 >"
str+= "<table border=2 cellspaci**g=1 cellpaddi**g=0 bordercolorlight=#ffffff bordercolordark=#c0c0c0 bgcolor=#e0e0e0>"
str+= " <tr>"
str+= " <td bgcolor=#e0e0e0 height=30px width=300px alig**=ce**ter>"
str+= " <fo**t color=black>系统正在处理中...</fo**t>"
str+= " </td>"
str+= " </tr>"
str+= " <tr>"
str+= " <td bgcolor=#e0e0e0>"
str+= " <img width=1 height=10 **ame=sbar style=backgrou**d-color:#6699cc>"
str+= " </td>"
str+= " </tr>"
str+= "</table> "
str+= "</layer>"
str+= "</div>"
docume**t.write(str)

if(docume**t.all)docume**t.o**click = checkclick;
}


测试文件testshowbar.html

<html>
<head>
<script la**guage="javascript" alt=" asp进度条 " src=http://www.yeahtech.com/study/showprocessbar.js></script>
</head>
<body>
<a href="error.asp" isshowprocessbar="true">a href</a>
<br>
<br>
<spa** o**click="locatio**.href='error.asp'" style="cursor:ha**d" isshowprocessbar="true"><fo**t color=blue>spa**</fo**t></spa**>
<br>
<form actio**="error.asp">
<i**put type=submit value="submit">
<i**put type=butto** value="**ormal butto**" isshowprocessbar="true">
</form>
<p isshowprocessbar="true">aaaaaaaaaaaaa</p>
</body>
</html>
本文标签:把本文收藏到 网摘 博采 百度
上一篇:ASP批量生成静态新闻          回网页设计列表         下一篇:页面加载进度条效果的实现
搜索本站其他内容: 百度一下:[asp网页进度条]   Google搜索:[asp网页进度条]
最新网友评论文章↓
1.靠2009-11-19 20:42:45
2.去2009-11-19 20:39:41
3.脑残还是变相炫富?2009-11-16 20:17:58
4.好感动哦2009-11-7 15:40:32
5.怎么学习2009-10-20 10:54:50

文章添加时间:2008-6-11,文件大小:20.23 KB,最近更新时间:2011-12-16 18:04:45 返回TOP↑            

本站文章搜集自网络;共享网络,共享快乐,我为人人,人人为我;如果您知道本站未知来源文章请告知本站谢谢!
文中及留言观点不代表本站;本站转载内容只是为了更好的交流;
若侵犯了您的版权请联系E-mail:有事儿,您Q我!,本站核实后立即处理!

  •             平面设计| 标志设计| 包装设计| 网页设计| 广告设计| VI设计| 画册设计| 专卖店设计| 展位设计| 名片设计| 网站地图|    建议使用IE5及以上1024*768分辨率
  •             友情链接 版权所有 © 杭州威迪广告公司 2008-2010 | TEL:0571-88385993 13296756810 浙ICP备09011107号