偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

使用XmlHttpRequest對(duì)象實(shí)現(xiàn)文件上傳進(jìn)度條

開(kāi)發(fā) 后端
本文向您介紹使用XmlHttpRequest對(duì)象實(shí)現(xiàn)文件上傳進(jìn)度條。其實(shí)就是通過(guò)XmlHttpRequest對(duì)象來(lái)向服務(wù)器發(fā)出異步請(qǐng)求,并從服務(wù)器獲得數(shù)據(jù),然后用javascript來(lái)操作DOM而更新頁(yè)面。

用過(guò)ajax的朋友應(yīng)該有聽(tīng)過(guò)Asp.Net XmlHttpRequest對(duì)象,ajax其實(shí)就是通過(guò)XmlHttpRequest對(duì)象來(lái)向服務(wù)器發(fā)出異步請(qǐng)求,并從服務(wù)器獲得數(shù)據(jù),然后用javascript來(lái)操作DOM而更新頁(yè)面。

本篇就是要通過(guò)XmlHttpRequest對(duì)象來(lái)實(shí)現(xiàn)實(shí)時(shí)的文件上傳進(jìn)度條顯示。

效果圖:

點(diǎn)擊圖片可以在新窗口打開(kāi)

正文部分:

看過(guò)有些前輩的做法是通過(guò)設(shè)置HTTP請(qǐng)求的Refresh頭字段來(lái)定時(shí)刷新頁(yè)面從而顯示進(jìn)度,但是這樣就會(huì)帶動(dòng)整個(gè)頁(yè)面一起刷新,就算我們把進(jìn)度條做成單獨(dú)的頁(yè)面,效果仍舊不是太好。我之前試過(guò)用ajax的Timer組件,但是不知道是何原因,Timer控件在IIS下預(yù)覽時(shí)總是無(wú)法正常發(fā)揮作用。苦惱了好一陣子,懷疑是MS的BUG。最后發(fā)現(xiàn)了一個(gè)很好的替代辦法就是利用XmlHttpRequest對(duì)象來(lái)自己實(shí)現(xiàn)定時(shí)刷新,這樣每次只需向服務(wù)器請(qǐng)求很少的數(shù)據(jù),減少了對(duì)服務(wù)器的壓力,在后期的測(cè)試中,發(fā)現(xiàn)這個(gè)辦法確實(shí)很好用,而且在IIS下也一切正常(上圖就是IIS下運(yùn)行的效果)。

當(dāng)然如果光有進(jìn)度條沒(méi)有數(shù)據(jù),那這個(gè)進(jìn)度條也只能是個(gè)擺設(shè),所以我把接下來(lái)的內(nèi)容分成兩塊:進(jìn)度信息的保存、進(jìn)度的顯示

1、進(jìn)度信息的保存

首先我們要明白進(jìn)度條在這里反應(yīng)的是什么的進(jìn)度?毫無(wú)疑問(wèn)是文件上傳的進(jìn)度,我們對(duì)上傳的文件數(shù)據(jù)進(jìn)行了提取,也就是說(shuō)這個(gè)提取的進(jìn)度就是我們要顯示給客戶(hù)端的進(jìn)度,這樣才是文件上傳進(jìn)度條的意義。那就簡(jiǎn)單了,我們只要把已經(jīng)提取的文件大小與總的文件大小比對(duì)一下,就可以知道完成的百分比了??墒菃?wèn)題來(lái)了,我們?nèi)绾沃郎蟼髁硕嗌倭四?答案肯定是要用一個(gè)變量來(lái)保存已經(jīng)上傳的數(shù)據(jù)量。那這個(gè)變量要放在哪里才能讓我們既可以在進(jìn)度頁(yè)面中訪問(wèn),又可以在HTTP上傳模塊中訪問(wèn)呢?

大家肯定知道一般情況下,用戶(hù)在多個(gè)頁(yè)面之間訪問(wèn),會(huì)用到Session對(duì)象或URL傳值來(lái)進(jìn)行頁(yè)面之前的通信。但是前一篇所介紹的HTTP模塊并不屬于一個(gè)頁(yè)面,因此我們無(wú)法簡(jiǎn)單的應(yīng)用Session讓進(jìn)度頁(yè)面與上傳模塊實(shí)現(xiàn)通信。這里主要還是借鑒高山來(lái)客的思路:首先構(gòu)建一個(gè)用于存放文件信息的類(lèi),該類(lèi)主要用來(lái)保存文件信息,如:文件名,路徑,當(dāng)前上傳的數(shù)據(jù)量,上傳時(shí)間等。然后設(shè)置一個(gè)針對(duì)某次上傳的唯一ID做為頁(yè)面中通信的暗號(hào),擁有這個(gè)暗號(hào)的頁(yè)面才能獲取對(duì)應(yīng)于某次上傳的文件信息?,F(xiàn)在已經(jīng)有了兩個(gè)變量了,接著就要使這兩個(gè)變量可以被多個(gè)頁(yè)面所使用,方法就是在上傳頁(yè)面中,將這個(gè)ID變量注冊(cè)為該頁(yè)面的一個(gè)隱藏域,這樣包含這個(gè)頁(yè)面的HTTP請(qǐng)求流中就會(huì)包含那個(gè)上傳ID。另一個(gè)類(lèi)變量就保存在頁(yè)面緩存Cache中,并用上傳ID做為其編號(hào)。

現(xiàn)在假設(shè)已經(jīng)有了這么一個(gè)用于存放文件信息的類(lèi)UploadFileInfo。

首先我們要在上傳頁(yè)面的PageLoad中new一個(gè)ID,然后注冊(cè)一個(gè)隱藏域用來(lái)保存此ID,同時(shí)實(shí)例化UploadFileInfo類(lèi),并將相應(yīng)的信息寫(xiě)入該類(lèi),最后把該類(lèi)放入Catch:

  1. if (!IsPostBack)  
  2. {  
  3. UploadFileInfo ufi = new UploadFileInfo();  
  4. ufi.strFileGuid = Guid.NewGuid().  
  5. ToString;//用GUID來(lái)表示唯一的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中  

經(jīng)過(guò)以上步驟,我們就可以在HTTP模塊中訪問(wèn)了。

因?yàn)樵谶@次的HTTP請(qǐng)求流中包含了一個(gè)隱藏域,所以我們可以對(duì)獲取的HTTP請(qǐng)求流進(jìn)行分析,從而獲取相應(yīng)的上傳ID,也就是我們之前說(shuō)的暗號(hào)。然后通過(guò)Cache的編號(hào)找到Cache中的文件信息對(duì)象,從而我們可以在后來(lái)的數(shù)據(jù)讀取過(guò)程中對(duì)該對(duì)象的上傳數(shù)據(jù)量進(jìn)行修改。由于是放在Cache中,加之是一個(gè)引用對(duì)象,所以對(duì)該對(duì)象修改后,其它代碼訪問(wèn)到的都是最新的值。

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

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

2、文件上傳進(jìn)度條的顯示

從圖中我們可以看到,當(dāng)顯示進(jìn)度的時(shí)候,背后的頁(yè)面成灰色,并且無(wú)法響應(yīng)任何事件,有點(diǎn)類(lèi)似模態(tài)窗口。這個(gè)效果大家可以在網(wǎng)上查查,還是挺容易實(shí)現(xiàn)的。我這里有一段js顯示此效果的代碼(搜集于網(wǎng)上):

  1. functionModalDialog  
  2. (name,divid,width,height,leftop,topop,color)  
  3. {  
  4. this.name=name;//名稱(chēng)  
  5. this.div=divid;//要放入窗體中的元素名稱(chēng)  
  6. this.width=width;//窗體寬  
  7. this.height=height;//窗體高  
  8. this.leftop=leftop;//左側(cè)位置  
  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()//關(guān)閉窗體  
  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;  

接著講我們的重點(diǎn):如何實(shí)現(xiàn)定時(shí)局部刷新。關(guān)于XmlHttpRequest對(duì)象,我這里就不詳細(xì)講述了,提供大家一個(gè)關(guān)于此的手冊(cè)下載。為了大家更容易理解,我舉個(gè)小例子:

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

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

  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();//建立一個(gè)全局的工廠實(shí)例  
  97. varstrevent="";  
  98. functionrefresh(url,interval,div)  
  99. {//該方法我用來(lái)定時(shí)刷新,因?yàn)槌薙etTimeout還有一些其它活要干  
  100. varstr1="";  
  101. for(i=2;i〈arguments.length;i++)  
  102. {//因?yàn)榭赡苄枰⑿碌膁iv不只一個(gè),  
  103. 所以利用js的arguments來(lái)解決動(dòng)態(tài)參數(shù)的問(wèn)題  
  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);//調(diào)用該方法實(shí)現(xiàn)異部通信  
  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);//定時(shí)執(zhí)行該方法  

【編輯推薦】

  1. 配置ASP.NET AJAX概述
  2. 安裝ASP.NET AJAX的過(guò)程
  3. ASP.NET頁(yè)面請(qǐng)求原理淺析
  4. ASP.NET頁(yè)面靜態(tài)化四步走
  5. 淺析ASP.NET授權(quán)模塊
責(zé)任編輯:冰荷 來(lái)源: cnblogs
相關(guān)推薦

2009-11-24 15:23:50

PHP文件上傳進(jìn)度條

2024-08-06 14:29:37

2015-07-31 11:19:43

數(shù)字進(jìn)度條源碼

2023-12-11 17:15:05

應(yīng)用開(kāi)發(fā)波紋進(jìn)度條ArkUI

2024-06-13 08:15:00

2009-08-17 14:41:47

C#進(jìn)度條實(shí)現(xiàn)

2009-08-17 15:48:47

C# WinForm進(jìn)

2009-12-25 17:58:12

WPF進(jìn)度條

2023-11-30 11:38:29

CSS網(wǎng)頁(yè)進(jìn)度條

2021-11-02 07:44:36

CSS 技巧進(jìn)度條

2011-07-05 15:16:00

QT 進(jìn)度條

2021-09-27 10:43:18

鴻蒙HarmonyOS應(yīng)用

2024-07-25 08:55:47

進(jìn)度條水缸進(jìn)度動(dòng)畫(huà)效果

2012-07-13 13:52:54

Canvas

2009-08-17 17:15:48

C# 進(jìn)度條效果

2009-08-17 14:36:15

C#進(jìn)度條實(shí)現(xiàn)

2009-08-17 13:56:29

C#進(jìn)度條的使用

2012-01-17 13:58:17

JavaSwing

2009-06-06 18:54:02

JSP編程進(jìn)度條

2023-07-18 15:49:22

HTMLCSS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)