使用XML幫助上傳檔案 (轉)

worldblog發表於2007-12-09
使用XML幫助上傳檔案 (轉)[@more@]

作者 Marco Nanni


概述

  本文講解了一個使用技術的例子,使用該方法沒有傳統方法中的種種限制。 這個例子講述瞭如何使用MSXML3.0和ADO Stream來實現這種新的上傳方法。好處有很多,比如,不需要專用的上傳。

 
引言

  為了在HTML網頁中獲得上傳功能,在客戶端我們可以使用如下格式的FORM:

  ACTION="TargetURL."
  ENCTYPE="multipart/form-data"
  METHOD="post">
 
 

  這種方案在客戶端和端的使用都有很多限制。首先,我們必須使用POST方法,因為GET方法無法處理這樣的表單資料。並且,沒有什麼方法可以在不使用表單的情況下引發一個POST動作。把資料傳送給表單處理後,將會把處理程式作為新頁面載入,然後使用者會看到一個不討人喜歡的頁面轉換過程。
  ENCTYPE屬性為表單定義了MIME編碼方式,上傳檔案的表單的ENCTYPE屬性必須使用“multipart/form-data”。把這個屬性設定為“multipart/form-data”就建立了一個與傳統結構不同的POST緩衝區(複合結構),ASP的Request物件無法訪問這樣的表單內容。所以,我們可以使用Request.binaryRead方法來訪問這些資料,但是無法使用指令碼語言來完成這一切。Request.binaryRead方法返回一個VTarray型資料(只包含無符號一位元組字元的Variant型陣列)。但是指令碼語言只能處理Variant型資料。為了解決這個問題,只能使用專用的ASP上傳元件,或者IS擴充套件程式,比如CPSHOST.DLL。這是設計上的限制。
 
新的上傳方案

  需要按照如下步驟操作。
  客戶端:

使用MSXML 3.0建立一個XML文件
建立一個針對二進位制內容的XML節點
使用ADO Stream 將上傳的檔案資料放入該節點
使用物件把這個XML文件傳送給伺服器

  伺服器端:
從Request物件中讀出XML文件
讀出二進位制節點中的資料並且到伺服器上的檔案中。當然,我們也可以將其儲存到的BLOB型欄位中。
  在解釋這段程式碼之前,我們可以對這個方案進行一些思考。
 
對XML的思考

XML格式支援很多資料型別,比如numeric, float, character等等。很多作者將XML定義為ASCII格式,但是我們不能忽視,XML技術還可以使用“bin.base64”資料型別來描述二進位制資訊。這個特性在MS XML3.0解析器重得到完全的支援,但是目前還需要一些特別設定。該物件提供一些可以對二進位制資料進行完全控制的屬性:

  • obj_node.dataType - 該可讀寫的屬性定義了特定節點的資料型別。MSXML解析器支援更多的資料型別(參見MSDN:.com/library/psdk/xmlsdk/xmls3z1v.htm">)

  對於二進位制資料,我們可以使用“bin.base64”型別。

  • obj_node.nodeTypedValue - 該可讀寫屬性包含了按照制定型別表示的指定節點的資料。

  我們可以建立一個包含多個bin.base64型別節點的XML文件,節點中包含上傳的檔案。這點特性可以使用一個POST一次上傳多個檔案。

  我們可以使用物件和POST方法傳送一個XML文件給Web伺服器。該物件為HTTP伺服器提供了客戶端支援,允許在Web伺服器上傳送和接受MS XML物件。XMLHttpRequest是Inte Explorer 5內建的COM物件(不需要定製),並且傳送完畢後無需轉換頁面。

 
對ADO Stream物件的思考

  我們可以在客戶端建立一個包含一個或者多個二進位制節點的XML文件。我們還必須把檔案內容填入節點中。但是很不幸,指令碼語言不能訪問本地檔案,並且Scripting.FileSystem物件(是系統的內建物件)到目前為止還不能訪問二進位制檔案。這是設計上的限制。所以我們需要另外找一個可以提供對本地二進位制檔案的訪問的COM物件。

  ADO Stream物件(MDAC 2.5中的元件)提供了讀、寫和管理二進位制流資料的手段。位元組流的內容可以是文字,或者二進位制資料,並且沒有容量上的限制。在ADO 2.5中,Microsoft對Stream物件的介紹不屬於ADO物件結構的任何一層,所以,我們無需捆綁即可使用該物件。

  本文中使用Stream物件來訪問檔案內容,再把內容存入XML節點。

 
客戶端

  以下示例程式碼使用Stream和MSXML物件完成檔案上傳動作。


File Send

 
 
Ready


 
伺服器端

  以下程式碼使用相同的物件提供伺服器端的上傳處理功能。


  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.SingleNode("root/file1")

  ' 開啟Stream物件,把資料存入其中 
  ado_stream.Type = 1  ' 1=adTypeBinary
  ado_stream.open
  ado_stream.Write xml_file1.nodeTypedValue
  ' 檔案存檔
  ado_stream.SaveToFile "c:tmpupload1.doc",2  ' 2=adSaveCreateOverWrite
  ado_stream.close

  ' 銷燬物件 
  set ado_stream = Nothing
  set xml_dom = Nothing
  ' 向瀏覽器返回資訊
  Response.Write "Upload succesul!"
%>

  也可以使用Stream物件把資料放到資料庫的BLOB型欄位中。
 
使用該方法的益處

  不引起頁面轉換。
  不需要專用元件。
  可同時上傳多個檔案。
  這段程式是純指令碼寫成的,可以很容易的插入到其他程式碼中,而不需要任何HTML物件的配合。還可以把這個邏輯在任何支援COM標準的語言中實現。
 
系統考慮

  該方法只能使用於內部,因為它需要的安全級別設定為“低”。必須:

  允許指令碼和ActiveX物件。該設定允許瀏覽器類似 "myobj = new activexobject(...)"的 語句;
  必須允許穿越域訪問資料來源。這個設定允許在客戶端使用Stream物件。還必須在伺服器和客戶端都安裝MS XML DOM 3.0 和MDAC 2.5 。
 
References


Read Tiago Halm's article about traditional file-upload processing at
For a description of the data types supported by MS XML parser, see and
A sample of creating an XML document with binary data in is available at
For a Microsoft reference on the ADO Stream object, see .
Another sample for managing BLOB and binary files can be found at .
 
About the Author

Marco Nanni is an Italian Web developer with experience in (D)HTML and XML technology used for implementing enterprise solutions. Marco can be contacted at: to:mnanni@lycos.it">mnanni@lycos.it.
 
 

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990573/,如需轉載,請註明出處,否則將追究法律責任。

相關文章