vbscript|vbscript 從瀏覽器上傳檔案是從客戶機向伺服器傳遞檔案的一個簡易方法。從第三代瀏覽器Netscape和 Microsoft起,多數瀏覽器都可以向伺服器上傳檔案,而不需要向使用者提供特殊的訪問方式或軟體。
一些ASP組件是為檔案上傳而設計的,例如:
Posting Acceptor
( Microsoft SiteServer的一部分),
AspSmartUpload(Advantys),
AspUpload (PersistsSoftware),
SA-FileUpSoftware Artisants)
本文的開始將告訴你關於建立這類組件的資訊,而這些組件通常使用VB、C++或Java。
這些組件的問題在於它們是第三方產品而非標準ASP的一部分。作為第三方組件,必須在伺服器上進行安裝。這就意味著必須在伺服器上複製DLL並註冊。大多數的主機系統不允許在他們的伺服器上進行這樣的設定,因為有可能發生配置問題(尤其是虛擬機器主機)。第二個缺點是它們大部分不是免費的,不提供原始碼,也就不能根據需要進行定製。
因此我需要編寫VBScript代碼來解決檔案上傳的問題。這不是一個必然的選擇,因為VBScript是一種指令碼語言,只能使用variants資料類型,並且不能提供許多管理位元據和位元組數組的內建函數。
要理解上傳的過程,首先要知道資料用HTTP協議從瀏覽器發送到伺服器的方式。這就意味著要理解“ multipart/form-data” (多部分/格式-資料)的表單提交。
上傳表單
通常情況下,使用HTML表單從瀏覽器向伺服器傳遞資料。這個表單中可能包含文本域、檢驗框、按鈕以及上傳檔案的檔案類型控制。使用者用自己的資料填充並將這個表提交給伺服器。
表單元素中的 enctype 屬性規定了傳遞給伺服器的表資料集編碼的內容類型。enctype 屬性的預設值是“application/x-www-form-urlencoded”,但當向伺服器傳送大量文本、包含非ASCII字元或位元的資料時,這個預設類型就不能勝任了。這時,檔案上傳提交表單時應使用“multipart/form-data”內容類型。
一個“multipart/form-data”資訊包含一系列組件,每個組件都可能包含:
一個Content-Disposition(內容-處理)頭,其值為"form-data" ;一個規定控制名的name(名稱)屬性。
對於一個檔案類型控制,一個組件可能包含更多資訊:
在客戶機上規定原始路徑和檔案名稱的filename(檔案名稱)屬性;所發送的位元據控制的Content-Type (內容-類型)頭。
在這些頭的後面跟隨著控制的二進位或常值內容。
以下例子說明“multipart/form-data”的編碼,客戶機的瀏覽器應有這個表單:
如果這個表單被提交,在伺服器上可讀到這些請求:
-----------------------------7cf87224d2020a
Content-Disposition: form-data; name="email"
PhCollignon@email.com
-----------------------------7cf87224d2020a
Content-Disposition: form-data; name="blob"; filename="c:\image.gif"
Content-Type: image/pjpeg
-----------------------------7cf87224d2020a
Content-Disposition: form-data; name="Enter"
Submit Query
-----------------------------7cf87224d2020a--
當那個內容作為響應被傳送回客戶機時就會被顯示出來。應該用Request.binaryRead 和Response.binaryWrite 方法讀和寫位元據。
〈%
Response.BinaryWrite(Request.BinaryRead(Request.TotalBytes))
%〉
可以看到響應的各部分用分界線來劃分:
-----------------------------7cf87224d2020a
最後一個分界線後面跟隨的是’ -- ’ 。
每一個控制都有一個Content-Disposition 。name屬性識別由HTML表發送的控制(email、blob和Enter)。 對於一個檔案類型控制(blob),
檔案名稱也是Content-Disposition 頭的一部分,Content-Type 頭給出二進位 資料的內容類型。
上傳指令碼
上面所有內容都必須經過分解。在VB 或 C++中, 這非常明顯,因為為此提供了許多個物件和方法。在VBScript 中,必須使用語言所提供的一些函數,並要解決VBScript中使用的雙位元組編碼的變數字串的問題。
VBScript函數
未經處理資料是二進位格式,所以必須使用專為管理位元據而設計的VBScript函數。因為我們將未經處理資料作為一個位元組的字串來考慮, 所以 MidB、InstrB 和 LenB 函數就有用了。 但是要避免VBScript的classic字串,因為它們是雙位元組編碼的字串,不適宜分解成單位元組。
這些是VBScript函數中僅有的用來分解位元組的函數。還需要一個方法,從被分解的資料中得到雙位元組編碼的字串,這樣就可以使用VBScript編碼中的字串了。為了在InstrB中把字串作為一個自變數使用,還需要一個函數,把雙位元組字元串轉換成單位元組字串。
為了我寫了兩個函數,getString() 和 getByteString(),稍後再對此進行解釋。
結構
分解的資料被儲存在VBScript Dictionary 對象中。 Dictionary 對象是hash 表對象,它儲存(key, item)對。它是VBScript和ASP2.0的一部分。
定義第一個Dictionary 對象 " UploadRequest " 。這個對象包含由上傳表提交的所有控制。Key是控制的名字,Item則是對象中所包含的控制的資訊:
"ControlName1", Dictionary control1
"ControlName2", Dictionary control2
代表一個控制的Dictionary 對象包含著下面的(key, item) 對:
"Value", String or binary content
"FileName", Name of uploaded file
"ContentType", ContentType of uploaded file
把這些結合起來,就有以下例子:
UploadRequest : "email", UploadControl 1 : "Value", PhCollignon@email.com
"blob" , UploadControl 2 : "filename", C:/image/file.gif "ContentType" :
image/gif "Value" : GIF89ai?
這個對象對於以後存取和使用資料非常有用。
分解
這裡是分解、讀和記錄上傳控制的代碼。這個過程用"BuildUploadRequest"程式來完成,這個程式只有一個自變數,就是原始位元據RequestBin。
Sub BuildUploadRequest(RequestBin)
首先要找到分界線,通過分界線可以知道控制迴圈何時結束。
’Get the boundary PosBeg = 1 PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(13)))
bou