利用 xmlhttp 分塊上傳檔案

來源:互聯網
上載者:User

編寫思路:把本地檔案在用戶端通過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)

用戶端代碼
<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></br> <DIV
id=div_message></DIV>
</body>
<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 End
Function
</script>
<script language=javascript> var xmlhttp ; var ado_stream ; var
mFileName, mPartStart, mPartID, mPartEnd ; var SendCount ; var
BlockSize ; var Breaked ; var aryFiles ; BlockSize = 1024*100
;//每次發送位元組數 Breaked = false ; aryFiles = new Array() ; // 開始傳送檔案
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() ;//檔案名稱 } 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 ;
SendCount = Math.ceil(ado_stream.size/BlockSize) ; // 如果有餘數則多發送一次 //
alert(SendCount) ; var reg = //b/w+./w+$/gi mFileName =
reg.exec(vFullPath) ; mPartStart = true ; mPartID = 1 ; mPartEnd =
false ; SendData() ; } function SendData() { if (SendCount > 0) {
var dom = new ActiveXObject("msxml2.DOMDocument"); // 發送的xml檔案
dom.async = false; dom.resolveExternals = false; // 構造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") ; // 分段結束標記 att.value = mPartEnd ;
node.setAttributeNode(att) ; att = null ; 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 ; } if (SendCount > 0) { mPartID += 1 ; //
div_message.innerHTML += ("<br>" + 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 +
"傳送完畢!<br>" ; // 繼續傳下一檔案 ShowBar(0) ; var cFile = aryFiles.pop()
; SendFile(cFile) ; } } } 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>" ; }
</script>
</html>
服務端代碼
<%@ LANGUAGE=VBScript%>
<% Option Explicit
Response.Expires = 0 

' 定義變數和對象。
dim ado_stream
dim xml_dom
dim xml_data
dim str_filename
dim bol_PartStart
dim int_PartID
dim bol_PartEnd

' 建立 Stream 對象
set ado_stream = Server.CreateObject("ADODB.Stream")
' 從Request對象建立 XMLDOM對象
set xml_dom = Server.CreateObject("MSXML2.DOMDocument")
xml_dom.load(request)
' 讀出包含位元據的節點
set xml_data = xml_dom.selectSingleNode("root/upData")
str_filename = xml_data.getAttribute("FileName")
bol_PartStart = CBool(xml_data.getAttribute("PartStart"))
int_PartID = CInt(xml_data.getAttribute("PartID"))
bol_PartEnd = CBool(xml_data.getAttribute("PartEnd"))

' 開啟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.size
end if
ado_stream.Write xml_data.nodeTypedValue
' 檔案存檔
ado_stream.SaveToFile server.mappath(".") &"/"& str_filename,2
'儲存檔案 2=adSaveCreateOverWrite 
ado_stream.close

' 釋放資源
set ado_stream = Nothing 
set xml_dom = Nothing
' 向瀏覽器返回資訊
Response.Write "Upload successful!"& str_filename & int_PartID & bol_PartStart
%>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.