從瀏覽器上載文件是從客戶機向服務器傳遞文件的一個簡易方法。從第三代瀏覽器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"
[email protected]
-----------------------------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", [email protected]
"blob" , uploadcontrol 2 : "filename", c:/upload/200902/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
|||