上傳 這個問題已經不是什麼新鮮問題了,網上也有大把的教程,但大多數是授人以魚,而不授人以漁,經過辛苦的資料收集,思考,調試,整理,我基本上已經把這個問題從原理上搞清楚了,現在根據我自己的理解,在範常式序的基礎上,加以解釋,希望能對部分網友(比我還菜的:-))有所協助。
請諸位大蝦能對其中的不正或不良這處予以指正。
程式中stream對象的用法上參考了“化境HTTP上傳程式 Version 2.0”在代碼,在此對稻香老農和梁無懼表示衷心的感謝和由衷的敬意。
先來分析一下,為後面的資料分析演算法打點基礎,以下是我摘錄的一小段網頁中提交的位元據:
-----------------------------7d31ec15102d0
Content-Disposition: form-data; name="txtTitle"
滿腦的想法
-----------------------------7d31ec15102d0
Content-Disposition: form-data; name="filImage"; filename="F:\material\木紋背景\pic016.jpg"
Content-Type: image/pjpeg
? JFIF C
!!E.'.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE?€"
? } !1AQa"q2亼?#B繃R佯$3br?
侼s歊J佦=ǜ珻,%??Xm 銓鼽?幮??馹湕胄滙C?
儗 g?咶? tS?B矠:u隠c
g不t淒L琰h`啨0p
g殲41?9'$筵奆]矓?膁?摍? 渦"??
-----------------------------7d31ec15102d0
Content-Disposition: form-data; name="btnUpload"
Upload
-----------------------------7d31ec15102d0--
藍色的字元的內容我們應該熟悉吧,中間的亂碼就是上傳的檔案的內容,其實我們要做的就是將這一堆資料進行分析,挑出對我們有用的資料儲存下來就OK了。分析資料就是尋找一些標誌性的內容,如斷行符號分行符號,“----------”符號,用兩個指標確定兩個位置,然後提取資料,我的演算法不知道好不好,本人的資料結構是學得很爛的,十分sorry。
以下是一個完事的應用,其中的類定義可以與入另一個檔案,使用的時候只要用
<!--include file="LjUpload.cls"-->
命令包含進來就可以了。
LjUpload.asp:
<%@ Language=VBScript %>
<% option explicit %>
<script language=vbscript runat=server>
private srmRequestData 'adodb.stream對象,儲存從form中提交來的所有資料
private adTypeBinary 'adodb.stream對象的三數:返回位元據
private adTypeText 'adodb.stream對象的三數:返迴文本資料
private adModeRead 'adodb.stream對象的三數:對象可讀
private adModeWrite 'adodb.stream對象的三數:對象可寫
private adModeReadWrite 'adodb.stream對象的三數:對象可讀寫
class LjUpload '定義一個類,名稱為LjUpload。
private bytCrLf '單位元組的斷行符號分行符號,共2位元組
private bytSub '單位元組的“-”符號,共8位元組
private binData '位元據變數,儲存一個提交資料的複本,便於操作
private dicForm '儲存form文本域的資訊
private dicFile '儲存form檔案域的資訊
private strName 'form表單的輸入欄位名稱
private strValue 'form表單的輸入欄位值
private objFile '檔案資訊對象,儲存檔案相關的資訊,具體三看class LjFile的定義
private posB '位元據讀寫指標,開始指標
private posE '位元據讀寫指標,結束指標
public Charset '語言屬性設定
private sub Class_Initialize '類初始化過程
bytCrLf = getSBfromDB(vbcrlf)
bytSub = getSBfromDB("--------")
Charset = "gb2312" '預設語言屬性設定為簡體中文:gb2312
adTypeBinary = 1 '返回位元據
adTypeText = 2 '返迴文本資料
adModeRead = 1 '對象資料可讀
adModeWrite = 2 '對象資料可寫
adModeReadWrite = 3 '對象資料可讀寫
end sub
public sub GetData '類的開啟過程,上傳檔案及分析資料的過程
set srmRequestData = server.CreateObject("adodb.stream") '建立一個adodb.stream對象
srmRequestData.Type = adTypeBinary '指定返回資料類型
srmRequestData.Mode = adModeReadWrite '指定開啟模式
srmRequestData.Open '開啟對象
srmRequestData.Write request.BinaryRead(request.TotalBytes) '擷取所有form提交的資料
srmRequestData.Position = 0 '讀寫指標重新置放至對象頭部,寫資料,指標已指向對象尾
binData = srmRequestData.Read '在變數中儲存提交資料的複本,便於操作
set dicForm = server.CreateObject("scripting.dictionary") '用來儲存文本資訊
set dicFile = server.CreateObject("scripting.dictionary") '用來儲存檔案資訊
posB = instrb(binData,bytSub) '開始分析所擷取的位元據
posB = instrb(posB,binData,bytCrLf) + 2 '+2是加入斷行符號分行符號本身的長度
posB = instrb(posB,binData,getSBfromDB("name=""")) + 6
do until posB = 6 '控制條件的設定有多種方式,這裡的僅供三考
posE = instrb(posB,binData,getSBfromDB(""""))
strName = getTextfromBin(srmRequestData,posB,posE-posB)
posB = posE + 1 '指標移動到“"”的後面
posE = instrb(posB,binData,bytCrLf)
if instrb(midb(binData,posB,posE-posB),getSBfromDB("filename=""")) > 0 then '這是一個file域
posB = instrb(posB,binData,getSBfromDB("filename=""")) + 10
posE = instrb(posB,binData,getSBfromDB(""""))
set objFile = new LjFile '建立一個檔案資訊對象
if posE>posB then
objFile.FileName = getFileNamefromPath(getTextfromBin(srmRequestData,posB,posE-posB)) '寫入檔案名稱
posB = instrb(posB,binData,getSBfromDb("Content-Type:")) + 14
posE = instrb(posB,binData,bytCrLf)
o