ASP與ActiveX控制項互動實戰

來源:互聯網
上載者:User
active|activex|互動|控制項
關鍵字:ASP,ActiveX控制項,數位簽章,安全

ActiveX控制項運行在用戶端。我們可以獲得用戶端的一些資訊,如IC卡的資訊,用戶端的驗證等等。但是ActiveX控制項也有許多缺點:用戶端的部署很困難,如用戶端不能正確下載,下載了以後不能正確執行,下載的時候需要設定IE的安全層級等等。

更多的時候,我都在使用COM組件來擴充ASP的功能。準確地說,是服務端啟動並執行Activex Dll組件。使用Server.CreateObject(“工程名.類名”)即可完成對組件的調用。這種方式問題很少,只要組件中以PUBLIC對外暴露方法既可。但是,有時候我們必須使用ACTIVEX 控制項(*.OCX)嵌入到網頁中執行來擷取用戶端的資訊。這就有了許許多多的一些問題。

這是我們需要解決的N個問題(從簡單到難)

1. 如何從服務端擷取資料,傳遞到ActiveX控制項中。

1) 初始化時使用參數綁定

2) 運行時得到資料

2. ActiveX控制項得到用戶端的資訊,如何傳遞到服務端。

3. 安全性

1) 數位簽章

2) 使用IOBJSAFE介面

好了,我們開始執行個體學習。

這個功能示範了如何製作一個簡單的控制項,並嵌入網頁中執行。

工作環境:WINXP+VB6+IE6

我的IE安全設定為安全層級-中。所有的Activex選項設為啟用。



開啟vb6,建立ActiveX控制項工程。

工程名:fOcx,使用者控制項名:UC1

為了方便,我們使用ActiveX控制項介面嚮導…,菜單->增益集->增益集管理器->VB 6 ActiveX控制項介面嚮導。確定即可。



開啟ActiveX控制項介面嚮導,下一步,對於可用名稱和選定名稱我們預設下一步,建立自訂成員,GetInfo類型:屬性,下一步,共有方法中選擇我們剛才添加的GetInfo,映射到控制項選擇TxtInfo,成員選擇Text,下一步直到完成。代碼視窗中會產生一些我們不需要的,刪除,剩下的代碼如下:

Option Explicit

'注意!不要刪除或修改下列被注釋的行!

'MappingInfo=txtinfo,txtinfo,-1,Text

Public Property Get GetInfo() As String

GetInfo = txtinfo.Text

End Property



Public Property Let GetInfo(ByVal New_GetInfo As String)

txtinfo.Text() = New_GetInfo

PropertyChanged "GetInfo"

End Property



'從存貯器中載入屬性值

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)

txtinfo.Text = PropBag.ReadProperty("GetInfo", "Text1")

End Sub

'將屬性值寫到儲存空間

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)

Call PropBag.WriteProperty("GetInfo", txtinfo.Text, "Text1")

End Sub

OK,好了,我們編譯成fOcx.ocx檔案,然後F5直接運行,VB會開啟一個測試頁。如下:

E:\Program Files\Microsoft Visual Studio\VB98\UC1.html

同時,開啟你的IE瀏覽器,看到了吧,你做的控制項出現在了這個測試頁中。

你可以開啟測試頁,可以看到ClsID,比如:890D1028-298B-45CF-9A64-6ED5A5BACBC9

因為VB編譯的時候已經完成註冊.所以無法類比用戶端沒有安裝該控制項時出現的提示.

我們繼續

使用regsvr32 F:\csdn_vb\com+_activeX\sample1\fOcx.ocx –u卸載

或者

開啟註冊表,在HKEY_CLASSES_ROOT\CLSID下面找到

890D1028-298B-45CF-9A64-6ED5A5BACBC9項,刪除之,當然這種方式還有項存在而沒有刪除乾淨.



此時瀏覽http://yang/uc1.htm,由於IE中ActiveX設定為啟動,所以,控制項會顯示出來。

下載後的ocx到哪裡去了???

開啟該目錄(可能有所不同)E:\WINDOWS.0\Downloaded Program Files,看到了吧,fOcx.UC1檔案在這個目錄下.

原理:用戶端下載該控制項後,自動註冊,然後放在上述這個目錄下.這時我們可以開啟註冊表看看CLSID,呵呵,還是以前的那個.

我們可以右鍵看看fOcx.UC1的屬性,看看相關內容,這裡顯示了該OCX所依賴的所有檔案.所以,你的OCX盡量減少使用進階控制項或者第三方的控制項,否則,下載就有些問題了.

如果IE中關於ActiveX的選項設為禁用,那麼瀏覽器就會出現對話方塊”當前安全設定禁止運行該頁中的ActiveX控制項.因此可能無法正確顯示該頁”,這個就需要其他的方式來處理了。

一般使用者預設的都是禁用ActiveX選項,所以讓使用者自己設定不太合適。
我們來看看如何從服務端擷取資料,傳遞到ActiveX控制項中。

1) 初始化時使用參數綁定

2) 運行時得到資料

開啟vb6,建立ActiveX控制項工程。

工程名:fOcx,使用者控制項名:UC2

為了方便,我們使用ActiveX控制項介面嚮導…,菜單->增益集->增益集管理器->VB 6 ActiveX控制項介面嚮導。確定即可。

開啟ActiveX控制項介面嚮導,下一步,對於可用名稱和選定名稱我們預設下一步,建立自訂成員,GetInfo類型:屬性,下一步,共有方法中選擇我們剛才添加的GetInfo,映射到控制項選擇TxtInfo,成員選擇Text,下一步直到完成。代碼視窗中會產生一些我們不需要的,刪除,

'注意!不要刪除或修改下列被注釋的行!

'MappingInfo=txtinfo,txtinfo,-1,Text

Public Property Get GetInfo() As String

GetInfo = txtinfo.Text

End Property

Public Property Let GetInfo(ByVal New_GetInfo As String)

txtinfo.Text() = New_GetInfo

PropertyChanged "GetInfo"

End Property

Private Sub Command1_Click()

Label2.Caption = GetInfo()

End Sub

'從存貯器中載入屬性值

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)

txtinfo.Text = PropBag.ReadProperty("GetInfo", "Text1")

End Sub

'將屬性值寫到儲存空間

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)

Call PropBag.WriteProperty("GetInfo", txtinfo.Text, "Text1")

End Sub

編譯成OCX控制項.運行產生的測試頁.Text中預設的是Text1

如何將伺服器端的資料傳遞給OCX呢?

使用Microsoft ActiveX Control Pad這個工具,可以很容易找到.

直接用這個工具把測試頁開啟.

菜單->Edit->Edit Activex Control,呵呵,開啟了一個可視化的介面.

看到了吧,有一個屬性框,我們可以進行設定,設定完成以後的代碼如下:

<HTML>

<HEAD>

<TITLE>New Page</TITLE>

</HEAD>

<BODY>

<OBJECT ID="GetClient" WIDTH=507 HEIGHT=440

CLASSID="CLSID:890D1028-298B-45CF-9A64-6ED5A5BACBC9"

CODEBASE="http://localhost/xml/fOcx.ocx">

<PARAM NAME="_ExtentX" VALUE="13414">

<PARAM NAME="_ExtentY" VALUE="11642">

<PARAM NAME="GetInfo" VALUE="這是ocx得到的用戶端讀卡機的資訊">

</OBJECT>

</BODY>

</HTML>

增加了ID,ID就是我們用來訪問的標誌.還有我們的屬性GetInfo,我們也設定初始值了

好了,運行.

Text中就出現了我們設定的值”這是ocx得到的用戶端讀卡機的資訊”

我們把上邊的頁面改成asp的,看代碼:

<HTML>

<HEAD>

<TITLE>龍捲風測試頁</TITLE>

</HEAD>

<BODY>

<%

dim sValue

sValue="這是ocx得到的用戶端讀卡機的資訊"

%>

<OBJECT ID="GetClient" WIDTH=507 HEIGHT=440

CLASSID="CLSID:56DFCA88-F5B8-4879-853B-97FE504423FD"

CODEBASE="http://localhost/xml/fOcx.ocx">

<PARAM NAME="_ExtentX" VALUE="13414">

<PARAM NAME="_ExtentY" VALUE="11642">

<PARAM NAME="GetInfo" VALUE="<%=sValue%>">

</OBJECT>

</BODY>

</HTML>

OK,運行即可

我們看看第二種情況

運行時得到資料


<HTML>

<HEAD>

<TITLE>龍捲風測試頁</TITLE>


<%

dim sValue

sValue="這是ocx得到的用戶端讀卡機的資訊"

%>

<SCRIPT ID=clientEventHandlersJS LANGUAGE=javascript>

<!--

function button1_onclick()

{

GetClient.GetInfo='<%=sValue%>';

}

//-->

</SCRIPT>

</HEAD>

<BODY>

<OBJECT ID="GetClient" WIDTH=507 HEIGHT=440

CLASSID="CLSID:56DFCA88-F5B8-4879-853B-97FE504423FD"

CODEBASE="http://localhost/xml/fOcx.ocx">

<PARAM NAME="_ExtentX" VALUE="13414">

<PARAM NAME="_ExtentY" VALUE="11642">

</OBJECT>

<INPUT id=button1 type=button value=Button name=button1 LANGUAGE=javascript >

</BODY>

</HTML>

運行後,點擊按鈕即可看到效果.
問題提出:

ActiveX控制項得到用戶端的資訊,如何傳遞到服務端???

一種方法就是得到值後,使用Get,Post方式提交,這可能也是最常用的.

有沒有更好一些的方法呢?

能不能在控制項中直接向伺服器發出請求而得到資料呢?



開啟vb6,建立ActiveX控制項工程。

工程名:fOcx,使用者控制項名:UC3

添加1個按鈕,2個文字框

代碼如下:

Option Explicit

Private Sub Command1_Click()

'注意字串和數位寫法有些區別

'使用AsyncRead通過HTTP發送你的請求

UserControl.AsyncRead "http://yang/xml/activex.asp?s1=" & Text1.Text & "", vbAsyncTypeByteArray

UserControl.AsyncRead "http://yang/xml/activex.asp?s1=" & Text1.Text, vbAsyncTypeByteArray

End Sub

'AsyncReadComplete 事件用來從asp頁面接受和分析。

'當容器剛完成一個非同步讀取請求時 , 發生該事件?

'AsyncProp 中的數值指定了已完成的某個非同步資料讀取請求,

'它與前一個 AsyncRead 方法調用中的資料匹配。

'AsyncReadComplete 事件程序中應包含錯誤處理代碼,因為錯誤狀態會終止下載。

'如果發生了這種情況,當訪問 AsyncProperty 對象的 Value 屬性時將會發生錯誤。

Private Sub UserControl_AsyncReadComplete(AsyncProp As AsyncProperty)

On Error GoTo errhandle

Text2.Text = ByteArrayToString(AsyncProp.Value)

errhandle:

Err.Raise 601, "非同步讀取發生了錯誤", Err.Description

End Sub

'將位元組數群組轉換成字串

Public Function ByteArrayToString(bytArray() As Byte) As String

Dim sAns As String

sAns = StrConv(bytArray, vbUnicode)

ByteArrayToString = sAns

End Function

我們來看看http://yang/xml/activex.asp這個檔案

<%

dim str

str=request("s1")

if str="name" then

response.write ("龍捲風")

elseif str="age" then

response.write ("26")

else

response.write ("沒有可用資訊返回")

end if

%>

很簡單,使用request接受參數,response返回。



這個例子可以進一步處理,將伺服器名以屬性的方式傳遞給控制項。

比如:<PARAM NAME="ServerName" VALUE="192.168.0.1 ">

然後在程式中得到,就可以使用了,如:

UserControl.AsyncRead "http://192.168.0.1/xml/activex.asp?s1=" & Text1.Text & "", vbAsyncTypeByteArray

然後在程式中得到就可以靈活處理了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.