asp.net默认的上传组件支持进度条反映

对于web下的上传,实际上更多的时候不用上传太大东西,asp.net默认的上传组件足够用了,美中不足就是没有上传进度反映,所以现在要做的就是在asp.net默认的上传基础上加上进度反映。

关于web上传的原理,曾在以前有深入分析过《asp无组件上传进度条解决方案》《Asp无组件上传带进度条(续) 》,并有写过asp版的无组件上传进度条,在这里就不多赘述。相信很多人都看过思归发的《用ASP.NET上传大文件》,解决的方法是利用隐含的HttpWorkerRequest,用它的GetPreloadedEntityBody 和 ReadEntityBody方法从IIS为ASP.NET建立的pipe里分块读取数据,对于每块分块进行分析并存储为临时文件,相对比较复杂。

要实现进度条的实时反映,核心的技术就是对上传的数据进行“分块”读取,在读取每块数据时记录当前已上传的块数,根据分块的大小,即可知道已上传的大小,根据总大小,即可知道当前上传的进度。具体的技术还是利用隐含的HttpWorkerRequest,用它的GetPreloadedEntityBody 和 ReadEntityBody方法从IIS为ASP.NET建立的pipe里分块读取数据,只不过仅仅是分块和记录已上传块数而已,用不着对已上传的数据进行分析和处理,因为这部分复杂的工作已经由asp.net的上传组件给我们做了。

根据上面所述的原理,具体代码相对很简单,我写了一个例子,用一个专门的进度显示页面(Progress.aspx),通过定时刷新(XmlHttp, FF支持)来获取当前上传的进度信息,并实时反映到上传页面上。

progressInfo.asp

<%@language=vbscript enablesessionstate=false lcid=1033%>
<%
 Response.CacheControl = "no-cache"
 Response.Expires = -1
 Application.Lock
 If Application("count") >= 100 Then Application("count") = 0
 Application("count") = Application("count") + 1
 Application.UnLock
%>
var pb = new progressBar();
pb.setSize(100,<%=Application("count")%>);

progressInfo.htm

<script src="xmlLib.js"></script>
<style>
 .progressBar{
  width: 250px;
  height: 15px;
 }
 .progressInfo{
  width: 250px;
  height: 15px;
  border: 1px solid #000000;
  overflow: hidden;
  text-align: center;
  font-size: 9pt;
  padding-top: 1;
  position: absolute;
 }
 .progress{
  background-color: #5FFF3F;
  width: 0%;
  height: 15px;
  overflow: hidden;
 }
</style>

<script>
var r = "传输: {0}K 还未完成";
var s = "您的文件已经上传完成";
function progressBar()
{

 this.totalSize = 100;
 this.sizeCompleted = 0;
 this.percentDone = "0%";
 this.setSize = function(totalSize, size)
 {
  var oProgress = document.getElementById("progress");
  var oProgressInfo = document.getElementById("progressInfo");
  if (oProgress == null || oProgressInfo == null)
   return;

  if (totalSize <= 0)
   return;

  this.totalSize = totalSize;
  this.sizeCompleted = size;
  if (size < 0)
   this.sizeCompleted = 0;
  else if (size > this.totalSize)
   this.sizeCompleted = this.totalSize;

  var sizeLeft = 0;
  var progressInfoText = "";
  sizeLeft = this.totalSize - this.sizeCompleted;

  this.percentDone = Math.round(size / this.totalSize * 100) + "%";
  oProgress.style.width = this.percentDone;
  
  if (sizeLeft > 0)
   progressInfoText = r.replace("{0}", sizeLeft);
  else
   progressInfoText = s;

  oProgressInfo.innerHTML = progressInfoText;
 }
}

</script>
<div id="progressBar" class="progressBar">
 <div class="progressInfo" id="progressInfo" onselectstart="return false;">
  &nbsp;
 </div>
 <div class="progress" id="progress">
 </div>
</div>
<script language="JavaScript" type="text/javascript">
<!--
var iTimerID = null;
var xmlHttp = XmlHttpPool.pick();

LoadProgressInfo();
function LoadProgressInfo()
{
 var url = "progressInfo.asp"
 try
 {
  xmlHttp.open("GET", url, true);
  xmlHttp.send(null);
  xmlHttp.onreadystatechange = function()
  {
   LoadData(xmlHttp);
  }
 }
 catch(e)
 {
  alert(e)
 }
}

function LoadData(xmlhttp)
{
 if (xmlhttp.readyState == 4)
 {
  iTimerID = window.setTimeout("LoadProgressInfo()", 100);
  eval(xmlhttp.responseText);
 }
}

//-->
</script>

xmlLib.js

//
// Helper Funcs //
//

// used to find the Automation object name
function getDomDocumentPrefix() {
 if (getDomDocumentPrefix.prefix)
  return getDomDocumentPrefix.prefix;
 
 var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
 var o;
 for (var i = 0; i < prefixes.length; i++) {
  try {
   // try to create the objects
   o = new ActiveXObject(prefixes[i] + ".DomDocument");
   return getDomDocumentPrefix.prefix = prefixes[i];
  }
  catch (ex) {};
 }
 
 throw new Error("Could not find an installed XML parser");
}

function getXmlHttpPrefix() {
 if (getXmlHttpPrefix.prefix)
  return getXmlHttpPrefix.prefix;
 
 var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
 var o;
 for (var i = 0; i < prefixes.length; i++) {
  try {
   // try to create the objects
   o = new ActiveXObject(prefixes[i] + ".XmlHttp");
   return getXmlHttpPrefix.prefix = prefixes[i];
  }
  catch (ex) {};
 }
 
 throw new Error("Could not find an installed XMLHttp object");
}


//
// Start the Real Funcs //
//

// XmlHttp factory
function XmlHttp() {}

XmlHttp.create = function () {
 try {
  // NS & MOZ
  if (window.XMLHttpRequest) {
   var req = new XMLHttpRequest();
   
   // some versions of Moz do not support the readyState property
   // and the onreadystate event so we patch it!
   if (req.readyState == null) {
    req.readyState = 1;
    req.addEventListener("load", function () {
     req.readyState = 4;
     if (typeof req.onreadystatechange == "function")
      req.onreadystatechange();
    }, false);
   }
   
   return req;
  }
  // IE
  if (window.ActiveXObject) {
   return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");
  }
 }
 catch (ex) {}
 // Fail
 throw new Error("Your browser does not support XmlHttp objects");
};

// XmlDocument factory
function XmlDocument() {}

XmlDocument.create = function () {
 try {
  // DOM2, MOZ & NS
  if (document.implementation && document.implementation.createDocument) {
   var doc = document.implementation.createDocument("", "", null);
   
   // some versions of Moz do not support the readyState property
   // and the onreadystate event so we patch it!
   if (doc.readyState == null) {
    doc.readyState = 1;
    doc.addEventListener("load", function () {
     doc.readyState = 4;
     if (typeof doc.onreadystatechange == "function")
      doc.onreadystatechange();
    }, false);
   }
   
   return doc;
  }
  if (window.ActiveXObject)
   return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");
 }
 catch (ex) {}
 throw new Error("Your browser does not support XmlDocument objects");
};

// Create the loadXML method and xml getter for Mozilla
if (window.DOMParser &&
 window.XMLSerializer &&
 window.Node && Node.prototype && Node.prototype.__defineGetter__) {

 // XMLDocument did not extend the Document interface in some versions
 // of Mozilla. Extend both!
 //XMLDocument.prototype.loadXML =
 Document.prototype.loadXML = function (s) {
  
  // parse the string to a new doc 
  var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
  
  // remove all initial children
  while (this.hasChildNodes())
   this.removeChild(this.lastChild);
   
  // insert and import nodes
  for (var i = 0; i < doc2.childNodes.length; i++) {
   this.appendChild(this.importNode(doc2.childNodes[i], true));
  }
 };
 
 
 /*
  * xml getter
  *
  * This serializes the DOM tree to an XML String
  *
  * Usage: var sXml = oNode.xml
  *
  */
 Document.prototype.__defineGetter__("xml", function () {
  return (new XMLSerializer()).serializeToString(this);
 });
}

/*
 * xmlHttp Pool
 *
 * userage: var xmlhttpObj = XmlHttpPool.pick()
 */
var XmlHttpPoolArr = new Array();
var XmlHttpPoolSize = 100;
var XHPCurrentAvailableID = 0;

function XmlHttpPool() {}

XmlHttpPool.pick = function() {
 var pos = XHPCurrentAvailableID;
 XmlHttpPoolArr[pos] =  XmlHttp.create();
 
 XHPCurrentAvailableID >= (XmlHttpPoolSize-1) ? 0 : XHPCurrentAvailableID++
 
 return XmlHttpPoolArr[pos];
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值