編寫想法:把本地文件在客戶端透過base64編碼以後發送目的地.
測試過程中,上傳檔案過大,導致逾時不成功.
後來經過改善.把編碼分段發送.測試20M成功
寫目的:在傳統的解決方案裡面,一次一次選取上傳可以.但是在碰到把資料庫里文件路徑讀出來,並把這些文件上傳到一個地方的時候就比較麻煩.
如果得到路徑一個一個去找到用ftp當然也是可以的,但每次找這些文件我看都會比較費時。這裡寫這個主要就是為了透過資料庫裡的文件路徑取得文件.把文件一次批次上傳到一個地方.
其主要目的還是為了鍛鍊一下自己.
解決過程:起初試著用模擬鍵盤輸入強行賦值給file控制項用傳統的方法上傳。可是老碰到空值的情況,以至有很多文件沒有送出去。查閱一些資料,現在是把所有路徑通過資料庫取到然後寫到一個js裡。然後在前台用js讀取這些路徑,透過xmlhttp發送檔案。
因為ie不太喜歡xmlHttp.總認為他有惡意行為.所以老談出提示警告.所以操作的時候不能使用web路徑.只能用物理路徑去訪問它.
然後服務端有一文件來接收這些編碼,並對其進行解碼.所以我稱之為c/s. ^_^
目前很多程式碼還在完善中.
簡單介紹一下:
-------------------------------------------------- -----------
aryFiles.push(c://aaa.zip) ;
aryFiles.push(c://bbb.exe) ;
這裡為文件路徑和文件.可為多個
以後這個路徑也可以透過file控制項在客戶端取到
http://www.xxx.com/xxx/xxx.asp
這個是目的地,可以改為自己想要的地址.
ado_stream.LoadFromFile(server.mappath(.) &/& + str_filename)
server.mappath(.) &/& + str_filename 這裡是讀取檔.
server.mappath(.) &/& 路徑與存放路徑一致
ado_stream.SaveToFile server.mappath(.) &/& str_filename,2
server.mappath(.) &/& 這個為存放檔案的路徑. str_filename 為檔名
這裡讀取和存放都是放在程式所放目錄中.大家測試的時候也可以保持這樣即可
把第一段程式碼放到本機(eg:c:/upload.htm)
把第二段程式碼放到伺服器上,可以是本地伺服器,可以是公網伺服器.和上面的目的地保持一致
(eg:http://www.xxx.com/upload.asp or http:// localhost/www/upload.asp)
-------------------------------------------------- --------------
操作:找到第一段程式碼保存的地方。執行即可(eg:開啟c盤執行upload.htm)
客戶端程式碼</P><P><html><head></head><body> <input type=button onclick=BeginSendFiles(); value=發送/> <input type=button onclick=JavaScript: Breaked= true; value=中斷/> <div id=ddd width=300px></div> </br> <DIV id=div_message></DIV></body></P><P><script language=VBScript>Function bytes2BSTR(vIn) strReturn = For i = 1 To LenB(vIn) ThisCharCode = AscB(MidB(vIn,i ,1)) If ThisCharCode < &H80 Then strReturn = strReturn & Chr(ThisCharCode) Else NextCharCode = AscB(MidB(vIn,i+1,1)) strReturn = strReturn & Chr(CLng(ThisCharCode) * &H100 + CInt(NextCharCode)) i = i + 1 End If Next bytes2BSTR = strReturn>Endunction</scriptscript </P><P><script language=javascript> var xmlhttp ; var ado_stream ; var mFileName, mPartStart, mPartID, mPartEnd ; var SendCount ; var BlockSize ; var Breaked ; var aryFiles ;</P><P> BlockSize = 1024*100 ;//每次發送位元組數Breaked = false ; aryFiles = false ; aryFiles = false ; aryFiles = false ; new Array() ;</P><P> // 開始傳送檔案function BeginSendFiles() { initAryFiles() ; SendFile(aryFiles.pop()) ; } // 建構待傳送檔案的陣列function initAryFiles() { aryFiles.push(c://aaa.zip) ; aryFiles.push(c: //bbb.exe) ;//c://aaa.zip c://bbb.exe本機檔案aryFiles.reverse() ;//檔名}</P><P> function SendFile(vFullPath) { // 空檔則不執行上傳if (!vFullPath) { return ; } Breaked = false ; div_message.innerHTML = ; ado_stream = new ActiveXObject( ADODB.Stream); // 讀取檔案的串流ado_stream.Type = 1; ado_stream.Open(); ado_stream.LoadFromFile(vFullPath); // 讀取檔案ado_stream.position = 0 ;</P><P> SendCount = Math.ceil(ado_stream.size/BlockSize) ; // 如果有餘數則多發送一次</P ><P> // alert(SendCount) ;</P><P> var reg = //b/w+./w+$/gi mFileName = reg.exec(vFullPath) ; mPartStart = true ; mPartID = 1 ; mPartEnd = false ; SendData() ; }</P><P> function SendData() { if (SendCount > 0) { var dom = new ActiveXObject(msxml2) { if (SendCount > 0) { var dom = new ActiveXObject(msxml2 .DOMDocument); // 傳送的xml檔案dom.async = false; dom.resolveExternals = false;</P><P> // 建構xml檔頭var node = dom.createProcessingInstruction(xml,version='1.0'); dom.appendChild(node) ; node = null ; // 建構root節點var root = dom.createElement(root); dom.appendChild(root) ; dom.documentElement.setAttribute(xmlns:dt, urn:schemas-microsoft-com:datatypes); // 建構保存二進位資料的節點updata node = dom.createElement(upData) ; node.dataType = bin.base64 ; // bin。 base64編碼var att = dom.createAttribute(FileName) ; // 檔案名稱屬性att.value = mFileName ; node.setAttributeNode(att) ; att = null ; var att = dom.createAttribute(PartStart) ; // 分段開始標記att.value = mPartStart ; node.setAttributeNode(att) ; att = null ; var att = dom.createAttribute(PartID) ; // 分段序號att.value = mPartID ; node.setAttributeNode(att) ; att = null ; var att = dom.createAttribute(PartEnd) ; // 分段標記.value =結束標記; node.setAttributeNode(att) ; att = null ;</P><P> root.appendChild(node) ; node.nodeTypedValue = ado_stream.Read(BlockSize); // 節點資料從stream讀取,固定長度node = null ; SendCount -= 1 ; xmlhttp = new ActiveXObject(Microsoft.XMLHTTP); xmlhttp. open(POST,http://www.xxx.com/xxx/xxx.asp, false); //http://www.xxx.com/xxx/xxx.asp 為web路徑上的檔案xmlhttp.onreadystatechange= CallBack ; xmlhttp.send(dom); mPartStart = false ; xmlhttp = null ; } else { ado_stream.Close (); ado_stream = null ; } } function CallBack() { // 上傳成功if(xmlhttp.readystate == 4) { //檢查是否中斷上傳if(Breaked) { return ; }</P><P> if (SendCount > 0) { mPartID += 1 ; // div_message.innerHTML += ( + xmlhttp.ResponseText) ; var p = Math. floor((mPartID/(Math.ceil(ado_stream.size/BlockSize) + 1)) * 100) ; //計算進度百分比ShowBar(p) ; var t = setTimeout(SendData();, 1) ; } else { // 傳送完檔案//div_message.innerHTML += mFileName + 傳送完畢! ;</P><P> // 繼續傳下一檔ShowBar(0) ; var cFile = aryFiles.pop() ; SendFile(cFile) ; } } </P><P> }</P><P > function ShowBar(per) { // 進度條ddd.innerHTML = <table width='200' border=0 cellpadding='0' cellspacing='0' ><tr><td bgcolor='#6699FF'><input type=button style=' width: + per + % ; border:0px; background:#005599; color:#FFFFFF' value= + per + %> < /td></tr></table> ; }</P><P></script></html></P><P>
伺服器端
</P><P><%@ LANGUAGE=VBScript%><% Option ExplicitResponse.Expires = 0 </P><P>' 定義變數和物件。 dim ado_streamdim xml_domdim xml_datadim str_filenamedim bol_PartStartdim int_PartIDdim bol_PartEnd </P><P>' 建立Stream 物件set ado_stream = Server.CreateObject(ADODB.Stream)'Requests從物件建立 1ML_stream Server.CreateObject(MSXML2.DOMDocument)xml_dom.load(request)' 讀出包含二進位資料的節點set xml_data = xml_dom.selectSingleNode(root/upData)str_filename = xml_data.getAttribute(FileName)bol_PartStart = CBalfxml_data. ))int_PartID = CInt(xml_data.getAttribute(PartID))bol_PartEnd = CBool(xml_data.getAttribute(PartEnd))</P><P>' 開啟Stream對象,把資料存入其中ado_stream.Type = 1 ' 1=adTypeBinary ado_stream.open if not bol_PartStart then ado_stream.LoadFromFile(server.mappath(.) &/& + str_filename) ' 讀取檔案ado_stream.position = ado_stream.sizeend ifado_stream.Write xml_data.nodeTypedValue' 檔案記憶體ado_stream.SaveToFile server.mappath(.) &/& str_filename,2'儲存檔案2=adSaveCreateOverriteWado_stream. <P>' 釋放資源set ado_stream = Nothing set xml_dom = Nothing' 傳回瀏覽器訊息Response.Write Upload successful!& str_filename & int_PartID & bol_PartStart%> </P><P>