亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Delphi > 正文

用DELPHI為ASP開發文件上載組件

2019-11-18 18:57:23
字體:
來源:轉載
供稿:網友
ASP(Active Server Page)是微軟公司的產品,由于它編程很容易上手,能快速開發功能強大的動態網站,現在很多網站(特別是Intranet/Extranet內部網)采用了NT+IIS+ASP的模式,使得ASP成為目前較為流行的網站開發腳本語言。在WEB服務中,文件上載服務是一個很常見的功能,而WIN9X下的PWS沒有提供相關組件;NT下的IIS提供了一個Post Acceptor組件,但由于它要檢查用戶的WWW訪問權限而變得不太好用;也可以從Internet上下載有關組件,但這些大多都是商業組件,用于下載的是試用版,在使用時間或功能上都有限制。由于ASP可以調用標準的OLE/COM組件,我們可以用VB/VC/DELPHI等高級編程工具根據我們自己的要求來定制自己的ASP文件上載組件,滿足自己的應用系統要求。

下面將討論用DELPHI為ASP開發文件上載組件的原理和具體實現過程。


一、文件上載的實現原理

基于Web方式數據上傳,要遵從RFC1867標準,上載的文件數據也不例外。如用下面HTML頁面文件(delphiup.htm)選擇上載文件:

<!-- DelphiUp.htm:文件上載界面 -->

<html><head><title>文件上載</title></head><body>

用DELPHI編寫的文件上載組件實現文件上載

<form NAME="UploadForm" ACTION="delphiup.asp" METHOD="POST" ENCTYPE="mult
<p>文件另存為:<input TYPE=text NAME="SaveAs">

<p>請要選擇上載的文件:<input TYPE=file NAME="FileData">

<input type="submit" name="b1" value="確認上載"> </p>

</form>

</body></html>

當客戶端選擇了一個文件(如Test.TXT,其內容為“這里是一個用于上載的文件的內容。”)并按

“確認上載”按鈕提交數據后,服務器端程序收到的數據將具有如下形式:

-----------------------------7cf1d6c47c#13#10

Content-Disposition: form-data; name="SaveAs"#13#10#13#10

NewFileName#13#10

-----------------------------7cf1d6c47c#13#10

Content-Disposition: form-data; name="FileData"; filename="D: est.txt"

Content-Type: text/plain#13#10#13#10

這里是一個用于上載的文件的內容。#13#10

-----------------------------7cf1d6c47c#13#10

Content-Disposition: form-data; name="b1"#13#10#13#10

確認上載#13#10

-----------------------------7cf1d6c47c--

其中,“-----------------------------7cf1d6c47c”是分界符,用于分隔表單(Form)中的各個域;

#13#10是回車換行符的DELPHI表示。我們可以這樣認為,每個表單域的信息描述,都是以分界符加一對回車換行符#13#10開始;表單域名以“name="”開始,以“"”為結束;表單域值以兩對回車換行符#13#10#13#10開始,以一對回車換行符#13#10#加分界符結束;文件名稱以“filename="”開始,以“"”為結束。有了這些標志,我們就可以獲取表單域的名稱和值以及要上載的文件的名稱,從而實現文件數據的讀取和存儲了。


二、文件上載的實現過程

在理解上面提到的數據格式后,自己動手編寫一個文件上載組件對我們來說已經不是困難了。


(一)開始建立一個ASP組件的工程

如果您對用DELPHI開發OLE Automation Server的步驟不太熟悉的話,請參見《電子與電腦》1999年第06期的一篇文章《用DELPHI開發用于ASP的OLE Automation Server 》。

這里只簡要介紹一下操作步驟。

1、建立ActiveX Library工程

在DELPHI中選擇菜單File=》New...,在“New Item”對話框的ActiveX選項卡中選擇“ActiveX Library”,DELPHI會自動創建一個DLL工程
PRoject1。

2、建立Automation組件

在DELPHI中選擇菜單File=》New...,在“New Item”對話框的ActiveX選項卡中選擇“Automation Object”;然后在“Automation Object Wizard”對話框中輸入Class Name(如“UploadFile”),Instancing選擇“Multiple Instance”即可,單擊“OK”后DELPHI會自動創建一個TLB(Type Library)文件Project1_TLB.PAS和一個PAS(Unit)文件Unit1.PAS。在Type Library設計窗口中,將Project1改名為MyUpload,則該文件上載組件的OLE注冊碼為“MyUpload.UploadFile”。

3、引入ASP類型庫

為了使用ASP的五個內建對象(Request、Response、Server、application、session),需要引入ASP類型庫。我們主要利用Request對象讀取從客戶端傳遞到服務器端的數據。

在Project菜單中選擇“Import Type Library”,在“Import Type Library”對話框的“Type Libraries”列表選擇“Microsoft Active Server Pages Object Library(Version 2.0)”(如果沒有這個選項,請確定您的計算機上安裝了IIS3以上或PWS4以上并且ASP.DLL已正確注冊),DELPHI會自動創建一個TLB文件ASPTypeLibrary_TLB.PAS,其中有我們需要的ASP對象類型聲明。

4、定義OnStartPage、OnEndPage過程

當在ASP頁面上用Server.CreateObject創建一個OLE對象實例時,WEB服務器會調用其方法OnStartPage,將ASP應用環境信息傳遞給該對象,我們可以在該過程中獲取客戶端信息;當在ASP頁面中釋放一個OLE對象實例時,WEB服務器會調用其方法OnEndPage,我們可以在該過程中進行釋放內存等結束操作。在我們這個組件中,我們要用到其OnStartPage方法。

OnStartPage方法應該在Unit1.PAS中定義,OnStartPage的函數原型為:

procedure OnStartPage(AScriptingContext: IUnknown);

其中參數AScriptingContext是一個IScriptingContext類型變量,包含五個屬性(Request、Response、Server、Application、Session)分別對應ASP的五個內建同名對象。

我們需要在TLB定義窗口(View=》Type Library)中,為IUploadFile增加方法OnStartPage,其Declaration語句為“procedure OnStartPage(AScriptingContext: IUnknown);”。


(二)提取客戶端上傳的數據

該工作可以放在OnStartPage過程中進行。

利用AScriptingContext的屬性Request(類型為IRequest)中的屬性TotalBytes(請求信息內容長度)和方法BinaryRead可將客戶端上傳的請求信息數據讀取到一個Byte類型的數組中,然后按RFC1867標準定義的數據格式來分析和提取數據。

1、首先定義TUploadFile的幾個私有變量

在單元文件UP01.PAS(由Unit1.PAS另存)中加入對ASPTypeLibrary_TLB.PAS的引用(Uses),

然后加入

private

FContentLength : LongInt;//請求信息內容長度

FContentData : Variant;//內容數據,以數組形式存儲請求信息內容

FFileName, //要上載的文件名稱

FDelimeter : string; //表單域分界符

FScriptingContext : IScriptingContext;//ASP處理上下文環境內容

FFileDataStart, //文件數據開始位置

FFileDataEnd : LongInt; //文件數據結束位置


2、提取客戶端上傳的請求信息數據

//在OnStartPage事件中,獲取ASP上下文信息、請求信息內容、表單域的分界符、文件數據

procedure TUploadFile.OnStartPage(AScriptingContext: IUnknown);

var

ARequest : IRequest; //WWW請求對象

AOleVariant : OleVariant; //記錄請求信息內容長度

intDelimterLength : integer;//分界符長度

longIndex,ALongInt,longPos : LongInt;

ContentData : AnsiString;//請求信息內容的字符串表示

strTemp : string;

FindEndOfFileData : boolean;//是否找到文件數據結束位置

begin

//提取客戶端上傳的請求信息數據

FScriptingContext := AScriptingContext as IScriptingContext;//獲取ASP上下文信息

ARequest := FScriptingContext.Request;//獲取WWW請求信息

FContentLength := ARequest.TotalBytes;//請求信息內容長度

//創建動態數組,用于以數組形式存儲請求信息內容

FContentData := VarArrayCreate( [0,FContentLength], varByte );

//將請求信息內容存儲到數組中

AOleVariant := FContentLength;

FContentData := ARequest.BinaryRead( AOleVariant );//讀取請求信息內容

//將請求信息內容轉化為字符串,便于定位

ContentData := ';

for longIndex := 0 to FContentLength - 1 do

begin

ContentData := ContentData + chr( Byte( FContentData[ longIndex ] ));

if FContentData[ longIndex ] = 0 then break;//0表示內容結束

end;


3、獲取分界符、上載文件名稱

//獲取表單域的分界符

longPos := pos( #13#10,ContentData );//回車換行符所在位置

FDelimeter := Copy( ContentData,1,longPos-1);//該位置之前的內容為分隔符


//獲取帶源路徑的文件名稱,在請求信息內容中,文件名稱以

//filename="path/filename"的形式存儲

strTemp := 'filename="';//文件名稱在“filename="”之后

longPos := pos( strTemp, ContentData );//獲取“filename="”位置

if longPos <= 0 then

begin

FFileName := ';

FFileDataStart := -1;

FFileDataEnd := -2;

exit;

end;

//獲取下個雙引號“"”之前的內容,即帶源路徑的文件名稱

longPos := longPos + length( strTemp );

strTemp := ';

for longIndex := longPos to FContentLength - 1 do

if ContentData[ longIndex ] <> '"' then

strTemp := strTemp + ContentData[ longIndex ]

else break;

FFileName := strTemp;


4、獲取文件數據的在請求信息內容中的開始、結束位置

//文件數據開始位置在文件名稱后的第一個#13#10#13#10之后

delete( ContentData, 1, longIndex );

strTemp := #13#10#13#10;

FFileDataStart := longIndex + pos(strTemp, ContentData) + length(strTemp) - 1;


//文件數據結束位置在下一個#13#10和分界符之前

//由于文件數據可能包含非法字符,不能再用字符串定位函數POS

//查找下一個分界符的位置

FFileDataEnd := FFileDataStart;

intDelimterLength := length( FDelimeter );

FindEndOfFileData := false;

while FFileDataEnd <= FContentLength - intDelimterLength do

begin

FindEndOfFileData := true;

for ALongInt := 0 to intDelimterLength - 1 do

if Byte( FDelimeter[ ALongInt + 1 ] ) <>

FContentData[ FFileDataEnd + ALongInt ] then

begin

FindEndOfFileData := false;

break;

end;

if FindEndOfFileData then break;

FFileDataEnd := FFileDataEnd + 1;

end;

if not FindEndOfFileData then FFileDataEnd := FFileDataStart - 1//未找到分界符

else FFileDataEnd := FFileDataEnd - 3;//分界符,向前跳過#13#10

end;


(三)向ASP程序傳遞信息

在進行了(二)的操作之后,我們的上載組件可以根據ASP程序的要求向其傳遞數據了。目前可以提供的數據有:客戶端源文件名稱(FFileName,含路徑)、文件大?。‵FileDataEnd-FFileDataStart+1)。

首先應該在TLB設計窗口中聲明如下兩個方法GetFileName和GetFileSize。

1、返回客戶端源文件名稱(含路徑)

//返回客戶端源文件名稱(含路徑)

function TUploadFile.GetFileName: OleVariant;

begin

result := FFileName;//客戶端源文件名稱(含路徑)

end;

2、返回文件大小

//返回文件大?。˙ytes)

function TUploadFile.GetFileSize: OleVariant;

begin

result := FFileDataEnd - FFileDataStart + 1;

end;


(四)保存文件

在進行了(二)的操作之后,我們的上載組件可以根據ASP程序的要求保存文件了。首先應該在

TLB設計窗口中聲明如下兩個方法SaveFileAs和SaveFile。

1、按指定文件名稱保存文件

//按指定的文件名稱保存文件,參數FileName為指定的文件名稱,返回值True表示文件保存成功

function TUploadFile.SaveFileAs(FileName: OleVariant): OleVariant;

var

longIndex : LongInt;

AFile : file of byte;//以二進制的形式保存文件

byteData : Byte;

begin

result := true;

try

assign( AFile, FileName );

rewrite( AFile );

for longIndex := FFileDataStart to FFileDataEnd do

begin

byteData := Byte( FContentData[ longIndex ] );

Write( AFile, byteData );

end;

CloseFile( AFile );

except

result := false;

end;

end;

2、按缺省文件名稱保存文件

//按缺省文件名稱保存文件,將文件以同名文件保存在調用頁面所在目錄

function TUploadFile.SaveFile: OleVariant;

var

CurrentFilePath : string;

begin

//獲取調用頁面所在目錄

CurrentFilePath := FScriptingContext.Request.ServerVariables['PATH_TRANSLATED'];

CurrentFilePath := ExtractFilePath( CurrentFilePath );

//保存文件

result := SaveFileAs( CurrentFilePath + ExtractFileName( FFileName ));

end;


三、上載組件應用舉例

在我們的例子中,DelphiUp.HTM是文件上載界面,DelphiUp.ASP用來執行文件上載操作。

DelphiUp.ASP的代碼如下:

<!--DelphiUp.ASP:文件上載處理頁面-->

<html><head><title>文件上載</title></head><body>

<% dim Upload, FileName

set Upload = Server.CreateObject("MyUpload.UploadFile")

FileName = Upload.GetFileName

Response.Write "<br>正在保存文件《"&FileName&"》......"

if Upload.SaveFile then

Response.Write "<br>文件《"&FileName&"》上載成功。"

Response.Write "<br>文件大小為"&Upload.GetFileSize&"字節。"

else

Response.Write "<br>文件《"&FileName&"》上載失敗。"

end if

set Upload=nothing %>

</body></html>


四、幾點說明

1、由DELPHI自動生成的源代碼編譯的DLL文件大小有215K,可以在

ASPTypeLibrary_TLB.PAS的Interface段中將Uses中的單元除ActiveX外全部刪除,在

MyUpload_TLB.PAS中刪除Uses中所有單元,則生成的DLL文件大小可減少到61K。

2、以上方法同樣適用于CGI程序,不過要用TWebRequest對象。


以上程序在PWIN98+Delphi3.0+PWS4.0下調試通過。


上一篇:用Delphi進行OpenGL編程學習心得

下一篇:在Delphi程序中應用IE瀏覽器控件

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久久久一区探花| 欧美福利在线观看| 国产亚洲视频在线观看| 精品视频在线播放免| 久久精品国产v日韩v亚洲| 97色在线播放视频| 92国产精品视频| 8x拔播拔播x8国产精品| 亚洲一区二区三区在线免费观看| 国产日韩欧美中文在线播放| 亚洲欧美日韩在线一区| 色爱av美腿丝袜综合粉嫩av| 欧美洲成人男女午夜视频| 国产精品一区二区久久国产| 国产一级揄自揄精品视频| 日韩在线免费观看视频| 亚洲精品91美女久久久久久久| 精品久久久久久电影| 久热精品在线视频| 92裸体在线视频网站| www.亚洲一区| 欧美性高潮床叫视频| 成人激情视频免费在线| 国产精品视频专区| 日韩在线观看av| 日韩一区二区三区xxxx| 亚洲字幕在线观看| 美女少妇精品视频| 欧美午夜激情在线| 一级做a爰片久久毛片美女图片| 伊人久久男人天堂| 永久555www成人免费| 亚洲欧美综合另类中字| 国产精品视频区| 日韩欧美在线视频| 国产一区二区三区欧美| 91国内在线视频| 久久男人av资源网站| 亚洲高清福利视频| 91精品国产一区| 色偷偷88888欧美精品久久久| 2018中文字幕一区二区三区| 国产精品a久久久久久| 欧美黑人又粗大| 欧美日韩视频免费播放| 欧美老女人性视频| 久久欧美在线电影| 日本免费一区二区三区视频观看| 亚洲精品白浆高清久久久久久| 精品国产一区二区三区久久狼黑人| 2019亚洲男人天堂| 亚洲欧美综合区自拍另类| 日韩欧美成人区| 精品一区精品二区| 日本精品久久久久久久| 国产欧美久久久久久| 北条麻妃一区二区在线观看| 国产在线视频不卡| 久久精视频免费在线久久完整在线看| 日韩中文字幕免费视频| 欧美日韩精品在线播放| 亚洲视频综合网| 清纯唯美日韩制服另类| 在线成人激情黄色| 午夜精品在线观看| 亚洲成av人片在线观看香蕉| 色偷偷综合社区| 最新国产成人av网站网址麻豆| 日韩电影中文字幕在线观看| 欧美天天综合色影久久精品| 亚洲精品v天堂中文字幕| 欧美精品九九久久| 91系列在线播放| 国产精品久久久久久久电影| 91久久精品视频| 国产精品精品久久久| 欧美激情一区二区三区在线视频观看| 国产乱肥老妇国产一区二| 日韩在线观看视频免费| 亚洲中国色老太| 亚洲精品456在线播放狼人| 91中文字幕在线观看| 欧美黑人巨大精品一区二区| 日韩**中文字幕毛片| 亲爱的老师9免费观看全集电视剧| 欧美电影免费观看高清完整| 欧美性猛交99久久久久99按摩| 777午夜精品福利在线观看| 国产精品精品一区二区三区午夜版| 日韩电影中文字幕一区| 亚洲国产高清福利视频| 国产网站欧美日韩免费精品在线观看| 日韩av大片在线| 丰满岳妇乱一区二区三区| 视频在线观看99| 亚洲深夜福利网站| 久久久成人精品视频| 日韩成人久久久| 狠狠躁夜夜躁久久躁别揉| 国产精品毛片a∨一区二区三区|国| 成人黄色午夜影院| 国产欧美日韩91| 国产在线视频欧美| 成人激情视频网| 日韩va亚洲va欧洲va国产| 国产成人福利视频| 色偷偷噜噜噜亚洲男人的天堂| 少妇av一区二区三区| 午夜精品久久久久久久99黑人| 欧美在线观看www| 国产精品白丝jk喷水视频一区| 精品久久中文字幕久久av| 理论片在线不卡免费观看| 性夜试看影院91社区| 国产一区二区三区在线| 国产精品自拍网| 国产欧美中文字幕| 成人免费福利在线| 久久韩国免费视频| 欧美激情精品久久久久久黑人| 亚洲综合第一页| 亚洲人成欧美中文字幕| 91视频国产精品| 欧美精品电影在线| 亚洲精品电影网| 亚洲国产成人爱av在线播放| 亚洲成年人在线| 九色成人免费视频| 国产精品视频公开费视频| 91sao在线观看国产| 亚洲一级片在线看| 97视频在线播放| 色青青草原桃花久久综合| 久久韩剧网电视剧| 狠狠爱在线视频一区| 亚洲高清av在线| 国产精品丝袜高跟| 日韩免费观看在线观看| 亚洲人成网站色ww在线| 最近免费中文字幕视频2019| 亚洲天堂网站在线观看视频| 亚洲第一中文字幕| 亚洲精品动漫100p| 精品久久久一区二区| 亚洲成人av在线播放| 国产精品高清免费在线观看| 97色伦亚洲国产| 国产日产欧美a一级在线| 最新国产精品拍自在线播放| 另类少妇人与禽zozz0性伦| 国产va免费精品高清在线观看| 欧美影院久久久| 中文字幕欧美精品在线| 91高潮在线观看| 大荫蒂欧美视频另类xxxx| 亚洲人成欧美中文字幕| 欧美日韩亚洲视频一区| 久久久亚洲精品视频| 国产欧美日韩精品在线观看| 亚洲国产毛片完整版| 国产激情综合五月久久| 亚洲国产日韩精品在线| 欧美精品久久久久a| 国产一区二区三区在线免费观看|