XML 網頁設計 技巧
本文講解左一個使用XML技術上傳文件既例子,用該方法冇傳統方法中既種種限制。 呢個例子講述左點去使用MSXML3.0和ADO Stream對象黎實現呢種新既上傳方法。好處有好多,比如,唔需要專用既上傳組件。
引言
為左在HTML網頁中獲得上傳功能,在客戶端我們可以使用如下格式的FORM:
<FORM NAME="myForm"ACTION="TargetURL.asp" ENCTYPE="multipart/form-data" METHOD="post"> <INPUT TYPE="file" NAME="myFile"> <INPUT TYPE="submit" VALUE="Upload File"> </FORM> |
呢種方案在客戶端和伺服器端的使用都有很多限制。首先,我們必須使用POST方法,因為GET方法無法處理咁樣既表單數據。並且,冇咩方法可以在唔使用表單既情況下引發一個POST動作。把數據發送給表單處理程式後,瀏覽器將會把處理程式作為新頁面加載,然後使用者會睇到一個不討人喜歡既頁面轉換過程。
ENCTYPE屬性為表單定義左MIME編碼方式,上傳文件既表單的ENCTYPE屬性必須使用“multipart/form-data”。把呢個屬性設置為“multipart/form-data”就創建左一個與傳統結構不同既POST緩衝區(複合結構),ASP既Request對象無法訪問咁既表單內容。所以,我們可以使用Request.binaryRead方法來訪問呢d數據,但係無法使用腳本語言來完成這一切。Request.binaryRead方法返回一個VTarray型數據(只包含無符號一字節字符的Variant型陣列)。但係腳本語言只能處理Variant型數據。為左解決這個問題,只能使用專用的ASP上傳組件,或者ISAPI擴展程式,比如CPSHOST.DLL。呢個係設計上既限制。
新既上傳方案
需要按照如下步驟操作。
客戶端:
使用MSXML 3.0創建一個XML文檔
創建一個針對二進製內容既XML節點
使用ADO Stream object將上傳的文件數據放入該節點
使用XMLHTTP對象把呢個XML文檔發送給Web伺服器
伺服器端:
從Request對象中讀出XML文檔
讀出二進製節點中既數據並且存儲到伺服器上既文件中。當然,我們也可以將其存儲到數據庫既BLOB型字段中。
在解釋呢段代碼之前,我們可以對呢個方案進行一d思考。
對XML的思考
XML格式支持很多數據類型,比如numeric, float, character等等。很多作者將XML定義為ASCII格式,但係我們不能忽視,XML技術還可以使用“bin.base64”數據類型來描述二進製資訊。呢個特性在MS XML3.0解析器重得到完全既支持,但係目前還需要一d特別設置。該對象提供一d可以對二進製數據進行完全控制既屬性:
obj_node.dataType - 該可讀寫既屬性定義左特定節點既數據類型。MSXML解析器支持更多既數據類型(參見MSDN:http://msdn.microsoft.com/library/psdk/xmlsdk/xmls3z1v.htm)
對於二進製數據,我們可以使用“bin.base64”類型。
obj_node.nodeTypedValue - 該可讀寫屬性包含左按照制定類型表示既指定節點的數據。
我們可以創建一個包含多個bin.base64類型節點既XML文檔,節點中包含上傳的文件。呢點特性可以使用一個POST一次上傳多個文件。
我們可以使用XMLHttpRequest對象和POST方法發送一個XML文檔給Web伺服器。該對象為HTTP伺服器提供左客戶端協議支持,允許在Web伺服器上發送和接受MS XMLDOM對象。XMLHttpRequest係Internet Explorer 5內置既COM對象(唔需要定製安裝),並且發送完畢後無需轉換頁面。
對ADO Stream對象的思考
我們可以在客戶端創建一個包含一個或者多個二進製節點的XML文檔。我們還必須把文件內容填入節點中。但係好不幸,腳本語本唔可以訪問本地文件系統,並且Scripting.FileSystem對象(是Win32系統的內置對象)到目前為止仲唔可以訪問二進製文件。呢個係設計上既限制。所以我們需要另外找一個可以提供對本地二進製文件的訪問既COM對象。
ADO Stream對象(MDAC 2.5中的組件)提供左讀、寫和管理二進製流數據既手段。位元組流的內容可以係文本,或者二進製數據,並且沒有容量上既限制。在ADO 2.5中,Microsoft對Stream對象的介紹唔屬於ADO對象結構既任何一層,所以,我們無需捆綁即可使用該對象。
本文中使用Stream對象來訪問文件內容,再把內容存入XML節點。
客戶端
以下示例代碼使用Stream和MSXML對象完成文件上傳動作。
<HTML> <HEAD><TITLE>File Send</TITLE></HEAD> <BODY> <INPUT id=btn_send name="btn_send" type=button value="FILE SEND"> <DIV id=div_message>Ready</DIV> </BODY> </HTML> <SCRIPT LANGUAGE=JavaScript> // 上傳函數 function btn_send.onclick() { // 創建 ADO-stream 對象 var ado_stream = new ActiveXObject("ADODB.Stream"); // 創建包含默認頭資訊和根節點的 XML文檔 var xml_dom = new ActiveXObject("MSXML2.DOMDocument"); xml_dom.loadXML('<?xml version="1.0" ?> <root/>'); // 指定數據類型 xml_dom.documentElement.setAttribute("xmlns:dt", "urn:schemas-microsoft-com:datatypes"); // 創建一個新節點,設置其為二進製數據節點 var l_node1 = xml_dom.createElement("file1"); l_node1.dataType = "bin.base64"; // 打開Stream對象,讀源文件 ado_stream.Type = 1; // 1=adTypeBinary ado_stream.Open(); ado_stream.LoadFromFile("c:tmpmyfile.doc"); // 將文件內容存入XML節點 l_node1.nodeTypedValue = ado_stream.Read(-1); // -1=adReadAll ado_stream.Close(); xml_dom.documentElement.appendChild(l_node1); // 可以創建多個二進製節點,一次上傳多個文件 // 把XML文檔發送到Web伺服器 var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.open("POST","./file_recieve.asp",false); xmlhttp.send(xml_dom); // 顯示伺服器返回的資訊 div_message.innerHTML = xmlhttp.ResponseText; } </SCRIPT> |
伺服器端
以下代碼使用相同的對象提供伺服器端的上傳處理功能。
<%@ LANGUAGE=VBScript%> <% Option Explicit Response.Expires = 0 ' 定義變量和對象。 dim ado_stream dim xml_dom dim xml_file1 ' 創建 Stream 對象 set ado_stream = Server.CreateObject("ADODB.Stream") ' 從Request對象創建 XMLDOM對象 set xml_dom = Server.CreateObject("MSXML2.DOMDocument") xml_dom.load(request) ' 讀出包含二進製數據的節點 set xml_file1 = xml_dom.selectSingleNode("root/file1") ' 打開Stream對象,把數據存入其中 ado_stream.Type = 1 ' 1=adTypeBinary ado_stream.open ado_stream.Write xml_file1.nodeTypedValue ' 文件存盤 ado_stream.SaveToFile "c:mpupload1.doc",2 ' 2=adSaveCreateOverWrite ado_stream.close ' 銷毀對象 set ado_stream = Nothing set xml_dom = Nothing ' 向瀏覽器返回資訊 Response.Write "Upload successful!" %> |
也可以使用Stream對象把數據放到數據庫既BLOB型字段中。
使用該方法既益處
不引起頁面轉換。
唔需要專用組件。
可同時上傳多個文件。
這段程式係純腳本寫成既,可以很容易既插入到其他代碼中,而唔需要任何HTML對象既配合。還可以把這個邏輯在任何支持COM標準既語言中實現。
系統安全考慮
該方法只能使用於內部網路,因為它需要IE5的安全級別設置為“低”。必須:
允許腳本和ActiveX對象。該設置允許瀏覽器執行類似 "myobj = new activexobject(...)"的 JScript語句;
必須允許穿越域訪問數據源。這個設置允許在客戶端使用Stream對象。還必須在伺服器和客戶端都安裝MS XML DOM 3.0 和MDAC 2.5 。
留言列表