带进度条的ASP无组件断点续传下载

  1. <%@LANGUAGE="VBSCRIPT"CODEPAGE="936"%><%OptionExplicit%><%'==================================''带进度条的ASP无组件断点续传下载'=================================='简介:'1)利用xmlhttp方式'2)无组件'3)异步方式获取,节省服务器资源'4)服务器到服务器的文件传送。(当然,你自己电脑上的IIS也是http服务器)'5)支持断点续传'6)分段下载'7)使用缓冲区,提升下载速度'8)支持大文件下载(速度我就不说了,你可以测,用事实说话)'9)带进度条:下载百分比、下载量、即时下载速度、平均下载速度''用法:'设置好下面的三个变量,RemoteFileUrl、LocalFileUrl、RefererUrl''作者:午夜狂龙(Madpolice)'[email protected]'2005.12.25'===============================%><%'------------为设置部分------<%Server.Scripttimeout=24*60*60'脚本超时设置,这里设为24小时%><%DimRemoteFileUrl'远程文件路径DimLocalFileUrl'本地文件路径,相对路径,可以包含/及..RemoteFileUrl="http://202.102.14.137/win98.zip"LocalFileUrl="win98.zip"DimRefererUrl'该属性设置文件下载的引用页,'某些网站只允许通过他们网站内的连接下载文件,'这些网站的服务器判断用户是否是在他们网站内点击的文件链接就是靠这个属性。RefererUrl="http://www.skycn.com/crack_skycn.html"'若远程服务器未限制,可留空DimBlockSize'分段下载的块大小DimBlockTimeout'下载块的超时时间(秒)BlockSize=128*1024'128K,按1M带宽计算的每秒下载量(可根据自己的带宽设置,带宽除以8),建议不要设的太小BlockTimeout=64'应当根据块的大小来设置。这里设为64秒。如果128K的数据64秒还下载不完(按每秒2K保守估算),则超时。DimPercentTableWidth'进度条总宽度PercentTableWidth=560%><%'--------------------以上为设置部分---------------%><%'***********************************'!!!以下内容无须修改!!!'***********************************%><%DimLocalFileFullPhysicalPath'本地文件在硬盘上的绝对路径LocalFileFullPhysicalPath=Server.Mappath(LocalFileUrl)%><%Dimhttp,adosOnErrorResumeNextSethttp=Server.CreateObject("Msxml2.ServerXMLHTTP.7.0")IfErrThenErr.ClearSethttp=Server.CreateObject("Msxml2.ServerXMLHTTP.6.0")IfErrThenErr.ClearSethttp=Server.CreateObject("Msxml2.ServerXMLHTTP.5.0")IfErrThenErr.ClearSethttp=Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")IfErrThenErr.ClearSethttp=Server.CreateObject("Msxml2.ServerXMLHTTP")IfErrThenErr.ClearResponse.Write"服务器不支持Msxml,本程序无法运行!"Response.EndEndIfEndIfEndIfEndIfEndIfOnErrorGoto0Setados=Server.CreateObject("Adodb.Stream")%><%DimRangeStart'分段下载的开始位置DimfsoSetfso=Server.CreateObject("Scripting.FileSystemObject")Iffso.FileExists(LocalFileFullPhysicalPath)Then'判断要下载的文件是否已经存在RangeStart=fso.GetFile(LocalFileFullPhysicalPath).Size'若存在,以当前文件大小作为开始位置ElseRangeStart=0'若不存在,一切从零开始fso.CreateTextFile(LocalFileFullPhysicalPath).Close'新建文件EndIfSetfso=Nothing%><%DimFileDownStart'本次下载的开始位置DimFileDownEnd'本次下载的结束位置DimFileDownBytes'本次下载的字节数DimDownStartTime'开始下载时间DimDownEndTime'完成下载时间DimDownAvgSpeed'平均下载速度DimBlockStartTime'块开始下载时间DimBlockEndTime'块完成下载时间DimBlockAvgSpeed'块平均下载速度DimpercentWidth'进度条的宽度DimDownPercent'已下载的百分比FileDownStart=RangeStart%><%DimadosCache'数据缓冲区DimadosCacheSize'缓冲区大小SetadosCache=Server.CreateObject("Adodb.Stream")adosCache.Type=1'数据流类型设为字节adosCache.Mode=3'数据流访问模式设为读写adosCache.OpenadosCacheSize=4*1024*1024'设为4M,获取的数据先放到(内存)缓冲区中,当缓冲区满的时候数据写入磁盘'若在自己的电脑上运行本程序,当下载百兆以上级别的大文件的时候,可设置大的缓冲区'当然,也不要设的太大,免得发生(按下浏览器上的停止按钮或断电等)意外情况导致缓冲区中的数据没有存盘,那缓冲区中的数据就白下载了%><%'先显示html头部Response.ClearCallHtmlHead()Response.Flush%><%DimResponseRange'服务器返回的http头中的"Content-Range"DimCurrentLastBytes'当前下载的结束位置(即ResponseRange中的上限)DimTotalBytes'文件总字节数Dimtemp'分段下载DownStartTime=Now()DoBlockStartTime=Timer()http.open"GET",RemoteFileUrl,true,"",""'用异步方式调用serverxmlhttp'构造http头http.setRequestHeader"Referer",RefererUrlhttp.setRequestHeader"Accept","*/*"http.setRequestHeader"User-Agent","Baiduspider+(+http://www.baidu.com/search/spider.htm)"'伪装成Baidu'http.setRequestHeader"User-Agent","Googlebot/2.1(+http://www.google.com/bot.html)"'伪装成Googlehttp.setRequestHeader"Range","bytes="&RangeStart&"-"&Cstr(RangeStart+BlockSize-1)'分段关键http.setRequestHeader"Content-Type","application/octet-stream"http.setRequestHeader"Pragma","no-cache"http.setRequestHeader"Cache-Control","no-cache"http.send'发送'循环等待数据接收While(http.readyState<>4)'判断是否块超时temp=Timer()-BlockStartTimeIf(temp>BlockTimeout)Thenhttp.abortResponse.Write"<script>document.getElementById(""status"").innerHTML=""<strong>错误:数据下载超时,建议重试。</strong>"";</script>"&vbNewLine&"</body></html>"CallErrHandler()CallCloseObject()Response.EndEndIfhttp.waitForResponse1000'等待1000毫秒Wend'检测状态Ifhttp.status=416Then'服务器不能满足客户在请求中指定的Range头。应当是已下载完毕。FileDownEnd=FileDownStart'设置一下FileDownEnd,免得后面的FileDownBytes计算出错CallCloseObject()ExitDoEndIf'检测状态Ifhttp.status>299Then'http出错Response.Write"<script>document.getElementById(""status"").innerHTML=""<strong>http错误:"&http.status&""&http.statusText&"</strong>"";</script>"&vbNewLine&"</body></html>"CallErrHandler()CallCloseObject()Response.EndEndIf'检测状态Ifhttp.status<>206Then'服务器不支持断点续传Response.Write<script>document.getElementById(""status"").innerHTML=""<strong>错误:服务器不支持断点续传!</strong>"";</script>"&vbNewLine&"</body></html>"CallErrHandler()CallCloseObject()Response.EndEndIf'检测缓冲区是否已满IfadosCache.Size>=adosCacheSizeThen'打开磁盘上的文件ados.Type=1'数据流类型设为字节ados.Mode=3'数据流访问模式设为读写ados.Openados.LoadFromFileLocalFileFullPhysicalPath'打开文件ados.Position=ados.Size'设置文件指针初始位置'将缓冲区数据写入磁盘文件adosCache.Position=0ados.WriteadosCache.Readados.SaveToFileLocalFileFullPhysicalPath,2'覆盖保存ados.Close'缓冲区复位adosCache.Position=0adosCache.SetEOSEndIf'保存块数据到缓冲区中adosCache.Writehttp.responseBody'写入数据'判断是否全部(块)下载完毕ResponseRange=http.getResponseHeader("Content-Range")'获得http头中的"Content-Range"IfResponseRange=""Then'没有它就不知道下载完了没有Response.Write"<script>document.getElementById(""status"").innerHTML=""<strong>错误:文件长度未知!</strong>"";</script>"&vbNewLine&"</body></html>"CallCloseObject()Response.EndEndIftemp=Mid(ResponseRange,Instr(ResponseRange,"-")+1)'Content-Range是类似123-456/789的样子CurrentLastBytes=Clng(Left(temp,Instr(temp,"/")-1))'123是开始位置,456是结束位置TotalBytes=Clng(Mid(temp,Instr(temp,"/")+1))'789是文件总字节数IfTotalBytes-CurrentLastBytes=1ThenFileDownEnd=TotalBytes'将缓冲区数据写入磁盘文件ados.Type=1'数据流类型设为字节ados.Mode=3'数据流访问模式设为读写ados.Openados.LoadFromFileLocalFileFullPhysicalPath'打开文件ados.Position=ados.Size'设置文件指针初始位置adosCache.Position=0ados.WriteadosCache.Readados.SaveToFileLocalFileFullPhysicalPath,2'覆盖保存ados.CloseResponse.Write"<script>document.getElementById(""downsize"").innerHTML="""&TotalBytes&""";</script>"&vbNewLineResponse.FlushCallCloseObject()ExitDo'结束位置比总大小少1就表示传输完成了EndIf'调整块开始位置,准备下载下一个块RangeStart=RangeStart+BlockSize'计算块下载速度、进度条宽度、已下载的百分比BlockEndTime=Timer()temp=(BlockEndTime-BlockStartTime)Iftemp>0ThenBlockAvgSpeed=Int(BlockSize/1024/temp)ElseBlockAvgSpeed=""EndIfpercentWidth=Int(PercentTableWidth*RangeStart/TotalBytes)DownPercent=Int(100*RangeStart/TotalBytes)'更新进度条Response.Write"<script>document.getElementById(""downpercent"").innerHTML="""&DownPercent&"%"";document.getElementById(""downsize"").innerHTML="""&RangeStart&""";document.getElementById(""totalbytes"").innerHTML="""&TotalBytes&""";document.getElementById(""blockavgspeed"").innerHTML="""&BlockAvgSpeed&""";document.getElementById(""percentdone"").style.width="""&percentWidth&""";</script>"&vbNewLineResponse.FlushLoopWhileResponse.IsClientConnectedIfNotResponse.IsClientConnectedThenResponse.EndEndIfDownEndTime=Now()FileDownBytes=FileDownEnd-FileDownStarttemp=DateDiff("s",DownStartTime,DownEndTime)If(FileDownBytes<>0)And(temp<>0)ThenDownAvgSpeed=Int((FileDownBytes/1024)/temp)ElseDownAvgSpeed=""EndIf'全部下载完毕后更新进度条Response.Write"<script>document.getElementById(""downpercent"").innerHTML=""100%"";document.getElementById(""percentdone"").style.width="""&PercentTableWidth&""";document.getElementById(""percent"").style.display=""none"";document.getElementById(""status"").innerHTML=""<strong>下载完毕!用时:"&S2T(DateDiff("s",DownStartTime,DownEndTime))&",平均下载速度:"&DownAvgSpeed&"K/秒</strong>"";</script>"&vbNewLine%></body></html><%SubCloseObject()Setados=NothingSethttp=NothingadosCache.CloseSetadosCache=NothingEndSub%><%'http异常退出处理代码SubErrHandler()DimfsoSetfso=Server.CreateObject("Scripting.FileSystemObject")Iffso.FileExists(LocalFileFullPhysicalPath)Then'判断要下载的文件是否已经存在Iffso.GetFile(LocalFileFullPhysicalPath).Size=0Then'若文件大小为0fso.DeleteFileLocalFileFullPhysicalPath'删除文件EndIfEndIfSetfso=NothingEndSub%><%SubHtmlHead()%><html><head><metahttp-equiv="Content-Type"content="text/html;charset=gb2312"><title>带进度条的ASP无组件断点续传下载----作者:午夜狂龙(Madpolice)--2005.12.25</title></head><body><divid="status">正在下载<spanstyle="color:blue"><%=RemoteFileUrl%></span>,请稍候...</div><div></div><divid="progress">已完成:<spanid="downpercent"style="color:green"></span><spanid="downsize"style="color:red"><%=RangeStart%></span>/<spanid="totalbytes"style="color:blue"></span>字节(<spanid="blockavgspeed"></span>K/秒)</div><div></div><divid="percent"align="center"style="display:''"><tablestyle="border-collapse:collapse;"border="1"bordercolor="#666666"cellpadding="0"cellspacing="0"width="<%=PercentTableWidth%>"align="center"bgcolor="#eeeeee"><trheight="20"><td><tableborder="0"width=""cellspacing="1"bgcolor="#0033FF"id="percentdone"><tr><td><td></tr></table></td></tr></table></div><%EndSub%><%'------------------------------'将秒数转换为"x小时y分钟z秒"形式'------------------------------FunctionS2T(ByVals)Dimx,y,z,tIfs<1ThenS2T=(s*1000)&"毫秒"Elses=Int(s)x=Int(s/3600)t=s-3600*xy=Int(t/60)z=t-60*yIfx>0ThenS2T=x&"小时"&y&"分"&z&"秒"ElseIfy>0ThenS2T=y&"分"&z&"秒"ElseS2T=z&"秒"EndIfEndIfEndIfEndFunction'-----------------------%>

ok!


你可能感兴趣的:(html,浏览器,cache,VBScript,asp)