作者: Phillip Perkins
2005-10-20 11:15 AM
我曾經讀過關於Mozilla擴充外掛程式AdBlock的一篇文章。該外掛程式允許使用者輸入過濾表達來限制瀏覽器接收的內容。這啟發了我,使我想到我也能在IE上應用同樣的方法限制資訊。在這篇文章中,我將建立一個基本的內容過濾器,它使用瀏覽器輔助對象(BHOs)功能來控制瀏覽器導航條。我們唯一需要討論的東西是映像和網頁。
瀏覽器輔助對象是一個在IE中啟動並執行ActiveX動態連結程式庫,它能執行與WebBrowser控制項一樣的功能,以及其他一些事件。當IE開啟一個網頁時,就產生了幾個事件。其中一個是BeforeNavigate2事件,它代替了WebBrowser控制項中以前的BeforeNavigate和 FrameBeforeNavigate事件。
在瀏覽器瀏覽到一個特定的URL地址之前,BeforeNavigate2事件發生。在這一事件中,傳遞了幾個參數,包括pDisp(事件來源的分配指標)、URL地址、導航標及PostData。你可以用pDisp指標來設定一個WebBrowser控制項當地變數。這讓我們擁有了控制項的所有功能,如Stor()方法。Stor()方法將阻止當前置航條,而且我們可以通過利用Navigate2()方法來瀏覽我們選擇的URL地址來補充我們的URL地址。
在這一過程中發生的另一個事件是NavigateComplete2事件,它代替了以前的NavigateComplete和FrameNavigateComplete事件。當瀏覽器完成瀏覽指定的URL地址時,NavigateComplete2事件發生。但是,在這個時間點,映像、對象和指令碼可能還在下載過程中。在這一事件中,我們可以用IE對象的文字屬性來檢查映像,以改變不良映像的src值。
為了識別不良URL地址,我們用規則的運算式來找出並攻擊這些URL地址。為方便使用,你可以將這些運算式儲存在一個單獨的文字檔中。我們對頁面及映像的URL地址進行測試來識別不良URL地址。沒有通過測試的URL將會轉到另一個更友好的URL地址,如一個“拒絕訪問”頁面或映像。
為了建立BHO功能,我們必須在Visual Basic中執行IobjectWithSite介面。參考一下我將包含在下載樣本中的類庫檔案,你就會擁有執行這一介面的能力。你還必須參考微軟指令碼運行期庫、微軟VB規則表達庫5.5、微軟互連網控制項陳列庫和微軟HTML物件程式庫。
以下為代碼:
Option Explicit
Option Base 0
Implements IObjectWithSiteTLB.IObjectWithSite
Dim WithEvents m_ie As InternetExplorer
Dim m_Site As IUnknownVB
Dim m_lError As Long
Dim m_sError As String
Dim sURLs As String
Private Sub Class_Initialize()
Dim fso As Scripting.FileSystemObject
Dim ts As Scripting.TextStream
Set fso = New Scripting.FileSystemObject
Set ts = fso.OpenTextFile(App.Path & "/urls.txt", ForReading, False)
sURLs = ts.ReadAll()
ts.Close
Set ts = Nothing
Set fso = Nothing
End Sub
Private Sub IObjectWithSite_GetSite(ByVal priid As
IObjectWithSiteTLB.GUIDPtr, ppvObj As IObjectWithSiteTLB.VOIDPtr)
m_Site.QueryInterface priid, ppvObj
End Sub
Private Sub IObjectWithSite_SetSite(ByVal pSite As
IObjectWithSiteTLB.IUnknownVB)
Set m_Site = pSite
Set m_ie = pSite
End Sub
Private Sub m_ie_BeforeNavigate2(ByVal pDisp As Object, URL As Variant,
Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers
As Variant, Cancel As Boolean)
Dim re As RegExp
Set re = New RegExp
Dim wbc As WebBrowser
m_lError = 0
m_sError = ""
re.Pattern = sURLs
If re.Test(URL) Then
Cancel = True
Set wbc = pDisp
wbc.Stop
wbc.Navigate2 "file:///" & Replace(Replace(App.Path &
"/access_denied.htm", ":", "|", 1, 1), "/", "/"), Flags, TargetFrameName
End If
Set re = Nothing
Set wbc = Nothing
End Sub
Private Sub m_ie_NavigateComplete2(ByVal pDisp As Object, URL As Variant)
Dim img As MSHTML.HTMLImg
Dim doc As MSHTML.HTMLDocument
Dim re As RegExp
Set doc = m_ie.document
Set re = New RegExp
re.Pattern = sURLs
For Each img In doc.images
If re.Test(img.src) Then _
img.src = "file:///" & Replace(Replace(App.Path &
"/access_denied.jpg", ":", "|", 1, 1), "/", "/")
Next
Set re = Nothing
Set img = Nothing
Set doc = Nothing
End Sub
除了IObjectWithSite_GetSite 和_SetSite步驟。還要注意當地變數m_ie要在IObjectWithSite_SetSite步驟中設定給pSite參數。這給了我們InternetExplorer對象的一個當地執行個體,還讓我們瞭解該對象中發生的事件---在類代碼頂部指定WithEvents變數。當這個類初始化時,URL限制即從相應的文字檔中載入。
在m_ie_BeforeNavigate2事件處理器中,你可以看到我利用pDisp參數得到解決的一個當地執行個體。我建立了一個RegExp對象來測試該URL。如果該URL不是我們想要的URL,就轉到一個當地的HTML檔案,這個檔案是一個類型的HTML檔案,它溫和地告訴使用者他們查看的URL不能訪問。
在m_ie_BeforeNavigate2事件處理器中,我得到一個HTMLDocument當地執行個體,然後我利用此當地執行個體來瀏覽所有的映像,並檢查不良RUL的src屬性。如果我遇到一個不良URL,就將它的src屬性轉到一個本地的JPEG映像,它告訴使用者此映像不允許查看。這種方法的缺點在於,當使用者重新整理網頁時,原始的映像就下載並顯示。
為了在IE中應用瀏覽器輔助對象,你必須用IEAdBlocker.AdBlock對象的類別識別項(CLSID)在註冊表的HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Explorer/Browser Help Objects路徑下建立一個新索引值。在編譯完代碼後,你就可以在註冊表的HKEY_CLASSES_ROOT/IEAdBlocker.AdBlock/Clsid條目下找到這個類別識別項。
這些代碼並不能完全解決問題。這一方法只簡單的表明哪些功能對IE和瀏覽器輔助對象有效。如果你勇於挑戰,你可以探索對C++開發人員有效功能來鑽研IE;精明的使用者甚至可以建立揭露對IE有效其他介面所必需的類型庫,如IdownloadManager。該例子的原始碼可從以下地址下載:http://www.phillipweb.com/Nov04/adblock.zip。
注意:編輯註冊表存在風險,在修改註冊表之前,一定要備份註冊表。