ASP无组件上传带进度条

<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%>
<%Option Explicit%>

<%
'================================================================
'
'                                带进度条的ASP无组件断点续传下载
'
'================================================================
'简介:
'        1)利用xmlhttp方式
'        2)无组件
'        3)异步方式获取,节省服务器资源
'        4)服务器到服务器的文件传送。(当然,你自己电脑上的IIS也是http服务器)
'        5)支持断点续传
'        6)分段下载
'        7)使用缓冲区,提升下载速度
'        8)支持大文件下载(速度我就不说了,你可以测,用事实说话)
'        9)带进度条:下载百分比、下载量、即时下载速度、平均下载速度
'
'用法:
'        设置好下面的三个变量,RemoteFileUrl、LocalFileUrl、RefererUrl
'
'================================================================
%>

<%'-----------------------------以下为设置部分--------------------------------%>
<%Server.Scripttimeout = 24 * 60 * 60        '脚本超时设置,这里设为24小时%>
<%
Dim RemoteFileUrl        '远程文件路径
Dim LocalFileUrl        '本地文件路径,相对路径,可以包含/及..

'速度问题注意:下面这个测试文件是在“网通”服务器上!!!
RemoteFileUrl = "http://hdt.driversky.com/down/foxmail60beta2.exe"
LocalFileUrl = "foxmail60beta2.exe"


Dim RefererUrl
'该属性设置文件下载的引用页,
'某些网站只允许通过他们网站内的连接下载文件,
'这些网站的服务器判断用户是否是在他们网站内点击的文件链接就是靠这个属性。
RefererUrl = "http://www.skycn.com/crack_skycn.html"        '若远程服务器未限制,可留空


Dim BlockSize        '分段下载的块大小
Dim BlockTimeout        '下载块的超时时间(秒)

BlockSize = 128 * 1024        '128K,按1M带宽计算的每秒下载量(可根据自己的带宽设置,带宽除以8),建议不要设的太小
BlockTimeout = 64        '应当根据块的大小来设置。这里设为64秒。如果128K的数据64秒还下载不完(按每秒2K保守估算),则超时。


Dim PercentTableWidth        '进度条总宽度

PercentTableWidth = 560
%>
<%'-----------------------------以上为设置部分--------------------------------%>

<%
'***********************************************************************
'                                        !!!以下内容无须修改!!!
'***********************************************************************
%>
<%
Dim LocalFileFullPhysicalPath        '本地文件在硬盘上的绝对路径

LocalFileFullPhysicalPath = Server.Mappath(LocalFileUrl)
%>

<%
Dim http,ados

On Error Resume Next
Set http = Server.CreateObject("Msxml2.ServerXMLHTTP.7.0")
If Err Then
        Err.Clear

        Set http = Server.CreateObject("Msxml2.ServerXMLHTTP.6.0")
        If Err Then
                Err.Clear

                Set http = Server.CreateObject("Msxml2.ServerXMLHTTP.5.0")
                If Err Then
                        Err.Clear

                        Set http = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
                        If Err Then
                                Err.Clear

                                Set http = Server.CreateObject("Msxml2.ServerXMLHTTP")
                                If Err Then
                                        Err.Clear
                                        Response.Write "服务器不支持Msxml,本程序无法运行!"
                                        Response.End
                                End If
                        End If
                End If
        End If
End If
On Error Goto 0

Set ados = Server.CreateObject("Adodb.Stream")
%>

<%
Dim RangeStart        '分段下载的开始位置
Dim fso

Set fso = Server.CreateObject("Scripting.FileSystemObject")
If fso.FileExists(LocalFileFullPhysicalPath) Then        '判断要下载的文件是否已经存在
  RangeStart = fso.GetFile(LocalFileFullPhysicalPath).Size        '若存在,以当前文件大小作为开始位置
Else
  RangeStart = 0        '若不存在,一切从零开始
  fso.CreateTextFile(LocalFileFullPhysicalPath).Close        '新建文件
End If
Set fso = Nothing
%>

<%
Dim FileDownStart        '本次下载的开始位置
Dim FileDownEnd        '本次下载的结束位置
Dim FileDownBytes        '本次下载的字节数
Dim DownStartTime        '开始下载时间
Dim DownEndTime        '完成下载时间
Dim DownAvgSpeed        '平均下载速度

Dim BlockStartTime        '块开始下载时间
Dim BlockEndTime        '块完成下载时间
Dim BlockAvgSpeed        '块平均下载速度

Dim percentWidth        '进度条的宽度
Dim DownPercent        '已下载的百分比

FileDownStart = RangeStart
%>

<%
Dim adosCache        '数据缓冲区
Dim adosCacheSize        '缓冲区大小

Set adosCache = Server.CreateObject("Adodb.Stream")
adosCache.Type = 1        '数据流类型设为字节
adosCache.Mode = 3        '数据流访问模式设为读写
adosCache.Open
adosCacheSize = 4 * 1024 * 1024        '设为4M,获取的数据先放到(内存)缓冲区中,当缓冲区满的时候数据写入磁盘

'若在自己的电脑上运行本程序,当下载百兆以上级别的大文件的时候,可设置大的缓冲区
'当然,也不要设的太大,免得发生(按下浏览器上的停止按钮或断电等)意外情况导致缓冲区中的数据没有存盘,那缓冲区中的数据就白下载了
%>

<%
'先显示html头部
Response.Clear
Call HtmlHead()
Response.Flush
%>

<%
Dim ResponseRange        '服务器返回的http头中的"Content-Range"
Dim CurrentLastBytes        '当前下载的结束位置(即ResponseRange中的上限)
Dim TotalBytes        '文件总字节数
Dim temp

'分段下载
DownStartTime = Now()

Do
        BlockStartTime = Timer()

        http.open "GET",RemoteFileUrl,true,"",""        '用异步方式调用serverxmlhttp

        '构造http头
        http.setRequestHeader "Referer",RefererUrl
        http.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)"        '伪装成Google
        http.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() - BlockStartTime
                If (temp > BlockTimeout) Then
                        http.abort
                        Response.Write "<script>document.getElementById(""status"").innerHTML=""<strong>错误:数据下载超时,建议重试。</strong>"";</script>" & vbNewLine & "</body></html>"
                        Call ErrHandler()
                        Call CloseObject()
                        Response.End
                End If

                http.waitForResponse 1000        '等待1000毫秒
        Wend

        '检测状态
        If http.status = 416 Then        '服务器不能满足客户在请求中指定的Range头。应当是已下载完毕。
                FileDownEnd = FileDownStart        '设置一下FileDownEnd,免得后面的FileDownBytes计算出错
                Call CloseObject()
                Exit Do
        End If

        '检测状态
        If http.status > 299 Then        'http出错
                Response.Write "<script>document.getElementById(""status"").innerHTML=""<strong>http错误:" & http.status & " " & http.statusText & "</strong>"";</script>" & vbNewLine & "</body></html>"
                Call ErrHandler()
                Call CloseObject()
                Response.End
        End If

        '检测状态
        If http.status <> 206 Then        '服务器不支持断点续传
                Response.Write "<script>document.getElementById(""status"").innerHTML=""<strong>错误:服务器不支持断点续传!</strong>"";</script>" & vbNewLine & "</body></html>"
                Call ErrHandler()
                Call CloseObject()
                Response.End
        End If

        '检测缓冲区是否已满
        If adosCache.Size >= adosCacheSize Then
                '打开磁盘上的文件
                ados.Type = 1        '数据流类型设为字节
                ados.Mode = 3        '数据流访问模式设为读写
                ados.Open
                ados.LoadFromFile LocalFileFullPhysicalPath        '打开文件
                ados.Position = ados.Size        '设置文件指针初始位置

                '将缓冲区数据写入磁盘文件
                adosCache.Position = 0
                ados.Write adosCache.Read
                ados.SaveToFile LocalFileFullPhysicalPath,2        '覆盖保存
                ados.Close

                '缓冲区复位
                adosCache.Position = 0
                adosCache.SetEOS
        End If

        '保存块数据到缓冲区中
        adosCache.Write http.responseBody        '写入数据

        '判断是否全部(块)下载完毕
        ResponseRange = http.getResponseHeader("Content-Range")        '获得http头中的"Content-Range"
        If ResponseRange = "" Then        '没有它就不知道下载完了没有
                Response.Write "<script>document.getElementById(""status"").innerHTML=""<strong>错误:文件长度未知!</strong>"";</script>" & vbNewLine & "</body></html>"
                Call CloseObject()
                Response.End
        End If
        temp = 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是文件总字节数
        If TotalBytes - CurrentLastBytes = 1 Then
                FileDownEnd = TotalBytes

                '将缓冲区数据写入磁盘文件
                ados.Type = 1        '数据流类型设为字节
                ados.Mode = 3        '数据流访问模式设为读写
                ados.Open
                ados.LoadFromFile LocalFileFullPhysicalPath        '打开文件
                ados.Position = ados.Size        '设置文件指针初始位置
                adosCache.Position = 0
                ados.Write adosCache.Read
                ados.SaveToFile LocalFileFullPhysicalPath,2        '覆盖保存
                ados.Close

                Response.Write "<script>document.getElementById(""downsize"").innerHTML=""" & TotalBytes & """;</script>" & vbNewLine
                Response.Flush
                Call CloseObject()
                Exit Do        '结束位置比总大小少1就表示传输完成了
        End If

        '调整块开始位置,准备下载下一个块
        RangeStart = RangeStart + BlockSize

        '计算块下载速度、进度条宽度、已下载的百分比
        BlockEndTime = Timer()
        temp = (BlockEndTime - BlockStartTime)
        If temp > 0 Then
                BlockAvgSpeed = Int(BlockSize / 1024 / temp)
        Else
                BlockAvgSpeed = ""
        End If
        percentWidth = 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>" & vbNewLine
        Response.Flush
Loop While Response.IsClientConnected

If Not Response.IsClientConnected Then
        Response.End
End If

DownEndTime = Now()
FileDownBytes = FileDownEnd - FileDownStart
temp = DateDiff("s",DownStartTime,DownEndTime)
If (FileDownBytes <> 0) And (temp <> 0) Then
        DownAvgSpeed = Int((FileDownBytes / 1024) / temp)
Else
        DownAvgSpeed = ""
End If

'全部下载完毕后更新进度条
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>

<%
Sub CloseObject()
        Set ados = Nothing
        Set http = Nothing
        adosCache.Close
        Set adosCache = Nothing
End Sub
%>

<%
'http异常退出处理代码
Sub ErrHandler()
        Dim fso

        Set fso = Server.CreateObject("Scripting.FileSystemObject")
        If fso.FileExists(LocalFileFullPhysicalPath) Then        '判断要下载的文件是否已经存在
                If fso.GetFile(LocalFileFullPhysicalPath).Size = 0 Then        '若文件大小为0
                        fso.DeleteFile LocalFileFullPhysicalPath        '删除文件
                End If
        End If
        Set fso = Nothing
End Sub
%>

<%Sub HtmlHead()%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>带进度条的ASP无组件断点续传下载</title>
</head>
<body>
<div id="status">正在下载 <span style="color:blue"><%=RemoteFileUrl%></span> ,请稍候...</div>
<div> </div>
<div id="progress">已完成:<span id="downpercent" style="color:green"></span> <span id="downsize" style="color:red"><%=RangeStart%></span> / <span id="totalbytes" style="color:blue"></span> 字节(<span id="blockavgspeed"></span>K/秒)</div>
<div> </div>
<div id="percent" align="center" style="display:''">
        <table style="border-collapse:collapse;" border="1" bordercolor="#666666" cellpadding="0" cellspacing="0" width="<%=PercentTableWidth%>" align="center" bgcolor="#eeeeee">
                <tr height="20">
                        <td>
                                <table border="0" width="" cellspacing="1" bgcolor="#0033FF" id="percentdone">
                                        <tr>
                                                <td> <td>
                                        </tr>
                                </table>
                        </td>
                </tr>
        </table>
</div>
<%End Sub%>

<%
'--------------------------------------------------------------------
'将秒数转换为"x小时y分钟z秒"形式
'--------------------------------------------------------------------
Function S2T(ByVal s)
        Dim x,y,z,t
        If s < 1 Then
                S2T = (s * 1000) & "毫秒"
        Else
                s = Int(s)
                x = Int(s / 3600)
                t = s - 3600 * x
                y = Int(t / 60)
                z = t - 60 * y
                If x > 0 Then
                        S2T = x & "小时" & y & "分" & z & "秒"
                Else
                        If y > 0 Then
                                S2T = y & "分" & z & "秒"
                        Else
                                S2T = z & "秒"
                        End If
                End If
        End If
End Function
'--------------------------------------------------------------------
%>

转载于:https://www.cnblogs.com/MaxIE/archive/2007/01/11/617655.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467204.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

广东阳西的小城生活

国庆放假&#xff0c;回小云老家&#xff0c;广东阳江阳西县。我们是昨天下午5点出发&#xff0c;晚上11点到家&#xff0c;刚好错开拥堵高峰&#xff0c;不过在沿江高速上川岛附近还是遇到了交通堵塞&#xff0c;一直缓缓前行&#xff0c;等到我们通过那个事故点的时候&#x…

React Native之箭头函数和延展操作符(...)

箭头函数 在我们学习React Native的过程中&#xff0c;我们经常会遇到">"这样形式的书写&#xff0c;如下&#xff1a; import React, {Component} from react import {AppRegistry, StyleSheet, View, Text, TouchableOpacity} from react-nativeclass RN_Arrow_…

读《爱的艺术》书评而问

豆瓣关于这本书的评论 我回复了这一篇评论 其实&#xff0c;更想拿这些问题和读者诸君交流&#xff0c;你们怎么看的&#xff1f; -------------------------------------------------------------------------------------- “一个成熟的人最终能达到他既是自己的母亲&#xf…

10.5 0819吉米牛逼

吉米真牛逼&#xff0c;这场比赛热火赢得漂亮&#xff0c;没有阿德巴约&#xff0c;没有德拉季奇的情况下&#xff0c;吉米硬生生把自己变成了詹姆斯。右侧45度拿球&#xff0c;突破顶着老詹急停跳投&#xff0c;又一次在老詹面前拿下两分&#xff0c;马上回防&#xff0c;面对…

flex 布局示例

1 <!DOCTYPE html>2 <html>3 4 <head>5 <meta charset"utf-8">6 <title>flex实例</title>7 <style>8 * {9 font-family: "微软雅黑";10 }11 12 html,…

既生Flash,又何生EEPROM?

我们正常编译生成的二进制文件&#xff0c;需要下载烧录到单片机里面去&#xff0c;这个文件保存在单片机的ROM中&#xff0c;ROM这个名称指的是「read only memory」的意思&#xff0c;所有可以完成「read only memory」这种特性的存储介质都可以称为ROM&#xff0c;我们一般使…

网吧电影服务器解决方案完全指南(一)

我们在这里所讲到的流媒体服务器&#xff0c;从本质上来讲&#xff0c;根本目的也是为了满足顾客这方面的要求。但相对于目前大多数网吧采用的系统来说&#xff0c;主要基于我们吸引顾客&#xff0c;在影视点播方面体现本网吧区别于其他竞争对手的特色。 <?xml:namespace p…

URLEncoder.encode问题

遇到java里的URLEncoder.encode方法编码后与javascript的encodeURIComponent方法的结果有点不一样&#xff0c;找了一下资料&#xff0c;原来URLEncoder实现的是HTML形式的规范&#xff0c;jdk文档里这么说&#xff1a; Utility class for HTML form encoding. This class cont…

数字油田

随着技术的进步和应用的深入&#xff0c;数字油田的概念也处于不断的发展之中&#xff0c;因此&#xff0c;到目前为止&#xff0c;数字油田尚无一个确切的概念&#xff0c;就目前的应用而言&#xff0c;数字油田一般可以描述为&#xff1a;数字油田是以油田为研究对象&#xf…

文本或代码中 \n 和 \r 的区别

我们使用printf打印时基本都会用到 \n 和 \r 之类控制字符&#xff0c;比如&#xff1a;printf("hello world!\r\n");那你知道这些 \n 和 \r 的区别吗&#xff1f;# 关于「 \n 」 和「 \r 」在ASCII码中&#xff0c;我们会看到有一类不可显示的字符&#xff0c;叫控制…

NYOJ276 比较字母大小

描述任意给出两个英文字母&#xff0c;比较它们的大小&#xff0c;规定26个英文字母A,B,C.....Z依次从大到小。 输入第一行输入T&#xff0c;表示有T组数据&#xff1b;接下来有T行&#xff0c;每行有两个字母&#xff0c;以空格隔开&#xff1b;输出输出各组数据的比较结果&am…

公布一个硬盘杀手的分析报告

这个东东不是新货了&#xff0c;最近发现受害者在增多&#xff0c;严重的是这个病毒破坏的硬盘数据&#xff0c;很难修复&#xff0c;有必要公布这个病毒的更多细节。病毒名&#xff1a;Win32.Troj.Small.cf.40960该病毒是一个硬盘杀手。该病毒会向硬盘分区的各分区起始扇区写入…

中兴5G和展锐原厂芯片开发,怎么选?

最近跟一个读友聊天&#xff0c;谈到的还是offer选择的问题&#xff0c;我觉得讨论这个问题比讨论技术问题更加重要「特别是刚出校门的学生&#xff0c;选择一个好的行业比刚毕业的薪资重要」。当然了&#xff0c;肯定有人跟我说我不务正业&#xff0c;整天瞎BB&#xff0c;好的…

qsort 三级排序

nyoj 一种排序 描述现在有很多长方形&#xff0c;每一个长方形都有一个编号&#xff0c;这个编号可以重复&#xff1b;还知道这个长方形的宽和长&#xff0c;编号、长、宽都是整数&#xff1b;现在要求按照一下方式排序&#xff08;默认排序规则都是从小到大&a…

梦中女孩,不知还能不能再见你一面

我将于茫茫人海之中&#xff0c;访我惟一灵魂伴侣&#xff0c;得之我幸&#xff0c;失之我命&#xff0c;如是而已.那天,第一次见到你,没有陌生的感觉,很熟悉很熟悉.那天,你走了,留给我的仅有一个浅浅的微笑.那天,没有机会和你告别,没有机会和你说声再会.那天,再一次见到你,我们…

40张动图揭示各种传感器工作原理!

应变加速度感应器▼称重式料位计▼电子皮带秤重示意图▼电子吊车秤▼荷重传感器用于测量汽车衡的原理▼荷重传感器的应用▼TiO2氧浓度传感器结构及测量电路▼布料张力测量及控制原理▼直滑式电位器控制气缸活塞行程▼电位器式传感器▼陶瓷湿度传感器▼多孔性氧化铝湿敏电容原理…

lpad与rpad

--lpad(str, n, [pad_str])--rpad(str, n, [pad_str])-- 如果n<length(str),则显示substr(str,1,n)-- 否则&#xff0c;分别从左边和右边使用pad_str进行填充-- 其中n表示最后输出结果字符串的长度-- 如果pad_str为空&#xff0c;则用空格来填充select lpad(abc,2,#) from d…

利用qsort二级排序

qsort int comp(const void *a,const void *b) { struct node*c(node*)a; struct node*d(node*)b; if(c->x!d->x) return c->x-d->x; else return c->y-d->y; } qsort(s,m,sizeof(s[0]),comp); qsort的二级排序完整代码&#xff1a; #include<stdio.…

git log 你学废了吗?

# 前言Git 是一个工具&#xff0c;用来管理代码的东西&#xff0c;要是Git 使用不好&#xff0c;确实还是挺尴尬的&#xff0c;我今晚看了个文章&#xff0c;发现Git log 是的玄机都还很多。比如这样的# git log --help如果觉得git 还不会用&#xff0c;可以看看git log --help…

部署WSE3.0实战:性能、证书与WSE910错误

早些时候看WSE3.0附带sample code&#xff0c;似乎挺简单&#xff0c;根据项目情况&#xff0c;选择UsernameForCertificate断言&#xff0c;使用测试服务证书在本机上&#xff08;winxp SP2&#xff09;执行很顺利&#xff0c;可以将Web service 部署到服务器上就得到“WSE 91…