成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用XmlHttpRequest對象實現文件上傳進度條

開發 后端
本文向您介紹使用XmlHttpRequest對象實現文件上傳進度條。其實就是通過XmlHttpRequest對象來向服務器發出異步請求,并從服務器獲得數據,然后用javascript來操作DOM而更新頁面。

用過ajax的朋友應該有聽過Asp.Net 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:

  1. if (!IsPostBack)  
  2. {  
  3. UploadFileInfo ufi = new UploadFileInfo();  
  4. ufi.strFileGuid = Guid.NewGuid().  
  5. ToString;//用GUID來表示唯一的ID;  
  6. ufi.strTempDir = Server.MapPath  
  7. ("TempUpload/" + ufi.strFileGuid + "http://");  
  8. ClientScript.RegisterHiddenField  
  9. ("UploadID", ufi.strFileGuid);  
  10. //隱藏域,名字為UploadID,值為ufi.strFileGuid  
  11. HttpContext.Current.Cache.Add(ufi.strFileGuid, ufi,   
  12. null, DateTime.Now.AddDays(10), TimeSpan.Zero,   
  13. System.Web.Caching.CacheItemPriority.High, null);//加入到Catch中  

經過以上步驟,我們就可以在HTTP模塊中訪問了。

因為在這次的HTTP請求流中包含了一個隱藏域,所以我們可以對獲取的HTTP請求流進行分析,從而獲取相應的上傳ID,也就是我們之前說的暗號。然后通過Cache的編號找到Cache中的文件信息對象,從而我們可以在后來的數據讀取過程中對該對象的上傳數據量進行修改。由于是放在Cache中,加之是一個引用對象,所以對該對象修改后,其它代碼訪問到的都是最新的值。

  1. string sguid = GetUploadId(bPreloadedEnitityBody,   
  2. eContentEncode);//GetUploadId  
  3. 是自己寫的一個方法用來從請求流中獲取上傳ID  
  4. UploadFileInfo ufiFileInfo = (UploadFileInfo)HttpContext.  
  5. Current.Cache[sguid];//取出文件信息對象 

其它頁面如果要使用這個對象就得先獲取ID,之后就可以自由操作了。

2、文件上傳進度條的顯示

從圖中我們可以看到,當顯示進度的時候,背后的頁面成灰色,并且無法響應任何事件,有點類似模態窗口。這個效果大家可以在網上查查,還是挺容易實現的。我這里有一段js顯示此效果的代碼(搜集于網上):

  1. functionModalDialog  
  2. (name,divid,width,height,leftop,topop,color)  
  3. {  
  4. this.name=name;//名稱  
  5. this.div=divid;//要放入窗體中的元素名稱  
  6. this.width=width;//窗體寬  
  7. this.height=height;//窗體高  
  8. this.leftop=leftop;//左側位置  
  9. this.topop=topop;//上部位置  
  10. this.color=color;//整體顏色  
  11. this.show=function()//顯示窗體  
  12. {  
  13. document.all(obj.name+"_divshow").style.  
  14. width=obj.width;  
  15. document.all(obj.name+"_divshow").style.  
  16. height=obj.height;  
  17. document.all(obj.name+"_divshow").style.  
  18. left=obj.leftop;  
  19. document.all(obj.name+"_divshow").style.  
  20. top=obj.topop;  
  21. document.all(obj.name+"_mask").style.  
  22. width=document.body.clientWidth;  
  23. document.all(obj.name+"_mask").style.  
  24. height=document.body.clientHeight;  
  25. document.all(obj.name+"_divshow").style.  
  26. visibility="visible";  
  27. document.all(obj.name+"_mask").style.  
  28. visibility="visible";  
  29. }  
  30. this.close=function()//關閉窗體  
  31. {  
  32. document.all(obj.name+"_divshow").style.width=0;  
  33. document.all(obj.name+"_divshow").style.height=0;  
  34. document.all(obj.name+"_divshow").style.left=0;  
  35. document.all(obj.name+"_divshow").style.top=0;  
  36. document.all(obj.name+"_mask").style.width=0;  
  37. document.all(obj.name+"_mask").style.height=0;  
  38. document.all(obj.name+"_divshow").  
  39. style.visibility="hidden";  
  40. document.all(obj.name+"_mask").  
  41. style.visibility="hidden";  
  42. }  
  43. this.toString=function()  
  44. {  
  45. vartmp="〈divid='"+this.name+"_divshow'  
  46. style='position:absolute;left:0;top:0;z-index:10;  
  47. visibility:hidden;width:0;height:0'〉";  
  48. tmp+="〈tablecellpadding=0cellspacing=  
  49. 0border=0width=100%height=100%〉";  
  50. tmp+="〈tr〉";  
  51. tmp+="〈tdid='"+this.name+"_content'valign=top〉〈/td〉";  
  52. tmp+="〈/tr〉" 
  53. tmp+="〈/table〉";  
  54. tmp+="〈/div〉";  
  55. tmp+="〈divid='"+this.name+"_mask'  
  56. style='position:absolute;top:0;left:0;width:0;height:0;  
  57. background:#666;filter:ALPHA(opacity=50);  
  58. z-index:9;visibility:hidden'〉〈/div〉";  
  59. document.write(tmp);  
  60. document.all(this.name+"_content").insertBefore  
  61. (document.all(this.div));  
  62. }  
  63. varobj=this;  

接著講我們的重點:如何實現定時局部刷新。關于XmlHttpRequest對象,我這里就不詳細講述了,提供大家一個關于此的手冊下載。為了大家更容易理解,我舉個小例子:

  1. //頁面A.aspx  
  2. functionreturnresponse(url)  
  3. {  
  4. varxmlHttp=newActiveXObject('MSXML2.xmlHttp');  
  5. if(xmlHttp!=null)  
  6. {  
  7. xmlHttp.open("GET",url,true);  
  8. //向URL指定的頁面發送GET請求  
  9. xmlHttp.onreadystatechange=function()  
  10. {//當xmlHttp的readyState  
  11. 改變的時候就會引發這個事件  
  12. if(xmlHttp.readyState==4&&xmlHttp.status==200)  
  13. {//4="成功發送",200="所請求的頁面返回正常" 
  14. temp=xmlHttp.responseText;  
  15. //接收所請求頁面發回的數據  
  16. alert(temp);  
  17. }  
  18. }  
  19. xmlHttp.send(null);  
  20. }  
  21. else 
  22. {  
  23. alert("瀏覽器不支持XmlHttp.");  
  24. }  
  25. }  
  26. //URL所指向的頁面B的代碼.cs,  
  27. 當然也可以是同一個頁面的cs  
  28. if(Request.QueryString["event"]=="test")  
  29. {  
  30. Response.Write("測試");  
  31. }  
  32.  
  33. /**//*  
  34. 然后我們在A頁中執行returnresponse  
  35. (B.aspx?event="test");  
  36. 很快就會發現在A頁中彈出一個窗口,內容是"測試"。  
  37. */ 

通過以上小例子,大家應該已經對該XmlHttpRequest對象有所了解了吧。為實現定時刷新,我把進度條單獨放在一個頁面中(如A.aspx),通過js的setTimeout來定時執行類似returnresponse這樣的方法,然后在A.aspx.cs代碼中獲取文件信息對象,接著通過Response來反饋進度信息。這樣在A.aspx頁面中就可以獲取到信息,并進行顯示了。但是執行ActiveXObject將要花費不少代價,而且我們是定時執行該方法,顯然會造成性能下降。在參考了構建一個pool來管理無刷新頁面的xmlhttp對象后,決定采用這一方法,事實證明該方法實現文件上傳進度條確實有效。

  1. functionxmlHttpPoolFactory()  
  2. {  
  3. this.XmlHttpPool=newArray();  
  4. this.MaxPoolLength=10;  
  5. this.Add=function()  
  6. {  
  7. if(this.XmlHttpPool.length〈this.MaxPoolLength)  
  8. {  
  9. xmlHttp=null;  
  10. if(window.XMLHttpRequest)  
  11. {//codeforallnewbrowsers  
  12. xmlHttp=newXMLHttpRequest();  
  13. }  
  14. elseif(window.ActiveXObject)  
  15. {//codeforIE5andIE6  
  16. try  
  17. {  
  18. xmlHttp=newActiveXObject('MSXML2.xmlHttp');  
  19. }  
  20. catch(e)  
  21. {  
  22. try  
  23. {  
  24. xmlHttp=newActiveXObject('Microsoft.xmlHttp');  
  25. }  
  26. catch(e2)  
  27. {  
  28. }  
  29. }  
  30. }  
  31. if(xmlHttp!=null)  
  32. {  
  33. this.XmlHttpPool.push(xmlHttp);  
  34. }  
  35. returnxmlHttp;  
  36. }  
  37. };  
  38. this.GetXmlHttp=function()  
  39. {  
  40. varxmlHttp=null;  
  41. varpool=this.XmlHttpPool;  
  42. for(vari=0;i〈pool.length;++i)  
  43. {  
  44. if(pool[i].readyState==4||pool[i].readyState==0)  
  45. {  
  46. xmlHttp=pool[i];  
  47. break;  
  48. }  
  49. }  
  50. if(xmlHttp==null)  
  51. {  
  52. returnthis.Add();  
  53. }  
  54. returnxmlHttp;  
  55. };  
  56. this.returnresponse=function(url,div)  
  57. {  
  58. varxmlHttp=this.GetXmlHttp();  
  59. varparam=div.split(',');  
  60. if(xmlHttp!=null)  
  61. {  
  62. xmlHttp.open("GET",url,true);  
  63. xmlHttp.onreadystatechange=function()  
  64. {  
  65. if(xmlHttp.readyState==4&&xmlHttp.status==200)  
  66. {//4="loaded",200="OK" 
  67. temp=xmlHttp.responseText;  
  68. vartemparray=temp.split(",");  
  69. document.getElementById(param[0]).  
  70. innerText=temparray[0];  
  71. document.getElementById(param[1]).  
  72. innerText=temparray[1]+"KB/S";  
  73. document.getElementById(param[2]).  
  74. innerHTML="  
  75. 〈tablewidth='"+temparray[2]*3+"' 〉  
  76. 〈tr 〉〈td 〉〈/td 〉〈/tr 〉〈/table 〉";  
  77. document.getElementById(param[3]).  
  78. innerText=temparray[2]+"%";  
  79. }  
  80. }  
  81. xmlHttp.send(null);  
  82. }  
  83. else 
  84. {  
  85. alert("YourbrowserdoesnotsupportxmlHttp.");  
  86. }  
  87. };  
  88. this.AportAll=function()  
  89. {  
  90. for(vari=0;i〈this.XmlHttpPool.length;++i)  
  91. {  
  92. this.XmlHttpPool[i].abort();  
  93. }  
  94. };  
  95. }  
  96. vara=newxmlHttpPoolFactory();//建立一個全局的工廠實例  
  97. varstrevent="";  
  98. functionrefresh(url,interval,div)  
  99. {//該方法我用來定時刷新,因為除了SetTimeout還有一些其它活要干  
  100. varstr1="";  
  101. for(i=2;i〈arguments.length;i++)  
  102. {//因為可能需要刷新的div不只一個,  
  103. 所以利用js的arguments來解決動態參數的問題  
  104. if(i!=arguments.length-1)  
  105. {  
  106. str1=str1+arguments[i]+",";  
  107. }  
  108. else 
  109. {  
  110. str1=str1+arguments[i];  
  111. }  
  112. }  
  113. a.returnresponse(url,str1);//調用該方法實現異部通信  
  114. varstr="";  
  115. for(i=0;i〈arguments.length;i++)  
  116. {  
  117. if(i!=arguments.length-1)  
  118. str=str+"'"+arguments[i]+"',";  
  119. else 
  120. str=str+"'"+arguments[i]+"'";  
  121. }  
  122. setTimeout("refresh("+str+")",interval);//定時執行該方法  

【編輯推薦】

  1. 配置ASP.NET AJAX概述
  2. 安裝ASP.NET AJAX的過程
  3. ASP.NET頁面請求原理淺析
  4. ASP.NET頁面靜態化四步走
  5. 淺析ASP.NET授權模塊
責任編輯:冰荷 來源: cnblogs
相關推薦

2009-11-24 15:23:50

PHP文件上傳進度條

2024-08-06 14:29:37

2015-07-31 11:19:43

數字進度條源碼

2023-12-11 17:15:05

應用開發波紋進度條ArkUI

2024-06-13 08:15:00

2009-08-17 14:41:47

C#進度條實現

2009-08-17 15:48:47

C# WinForm進

2009-12-25 17:58:12

WPF進度條

2023-11-30 11:38:29

CSS網頁進度條

2021-11-02 07:44:36

CSS 技巧進度條

2011-07-05 15:16:00

QT 進度條

2021-09-27 10:43:18

鴻蒙HarmonyOS應用

2024-07-25 08:55:47

進度條水缸進度動畫效果

2012-07-13 13:52:54

Canvas

2009-08-17 17:15:48

C# 進度條效果

2009-08-17 14:36:15

C#進度條實現

2009-08-17 13:56:29

C#進度條的使用

2012-01-17 13:58:17

JavaSwing

2009-06-06 18:54:02

JSP編程進度條

2023-07-18 15:49:22

HTMLCSS
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久99精品免费观看 | 91精品中文字幕一区二区三区 | 欧美一级片在线看 | 日韩精品免费一区 | 中文字幕一区二区三区在线乱码 | 精品国产伦一区二区三区观看说明 | 久久久精品网 | 国产精品一区在线观看你懂的 | 中文字幕在线一区 | 视频二区 | 亚洲精品乱码久久久久久蜜桃 | 国产乱精品一区二区三区 | 爱草在线 | 久草日韩 | 欧美日韩福利视频 | 久久久久久亚洲 | a欧美 | 婷婷福利视频导航 | 亚洲三区在线观看 | 欧美最猛性xxxxx亚洲精品 | 亚洲精选一区 | 噜久寡妇噜噜久久寡妇 | 国产精品一区二区三区99 | 999精品在线观看 | 成人在线国产 | 狠狠狠 | 亚洲第一福利视频 | 久久久久网站 | 欧美一区二区三区的 | 午夜在线视频一区二区三区 | 一区视频 | 不卡一区| www.4hu影院| 性欧美hd | 一级国产精品一级国产精品片 | 伊人性伊人情综合网 | 国产欧美一区二区三区在线看 | 一区二区精品在线 | 无码一区二区三区视频 | 国产成人精品午夜 | 国产一级片在线观看视频 |