2012-05-17 58 views
4

我試圖阻止任何外部由TEmbeddedWB或TWebBrowser(或TCppWebBrowser)加載。我想阻止從互聯網加載的任何內容,包括圖像,JavaScript,外部CSS,外部[嵌入]或[對象]或[小程序]或[框架]或[iframe],執行可加載外部內容的JavaScript等。檢測外部內容與TEmbeddedWB或TWebBrowser

此問題由兩個部分組成:

  • 把Web瀏覽器到「限制」的報告(除了沒有圖像基本的HTML),並且檢測是否這樣的內容存在
  • 如果外部內容不存在確定的,如果它顯示一個「下載欄」,點擊後將網頁瀏覽器放入「全部下載」模式並獲取所有內容。

第一個項目的問題。在TEmbeddedWB中,您可以使用DownloadOptions開關阻止幾乎任何事情,最重要的是ForceOffline開關,但即使關閉所有這些,仍會通過[object][iframe]標籤。我知道這是因爲我實現了OnBeforeNavigate2事件,它觸發了這些標記中包含的URL,並且它還在本地服務器的日誌中創建了一個條目。在TEmbeddedWB中設置OfflineModeForceOfflineMode對這些項目沒有幫助。

那麼我怎麼能真正阻止所有?因此,它需要以阻止的外部元素(包括腳本和CSS)作爲基本HTML開始。有沒有辦法在每次下載任何事件時觸發事件,以阻止所有外部下載,從而阻止或避免觸發此類事件?我需要擺弄Internet Explorer區域和安全嗎?正確方向的任何指針都會有所幫助。

第二項也很棘手,因爲我需要檢測是否存在問題標籤(例如「applet」,「腳本」,「鏈接」等。這種檢測不需要是完美的,但它至少必須是。好到足以覆蓋大部分此類標籤的我已經做了這樣的:

//---------------------------------------------------------------------- 
// Check for external content (images, scripts, ActiveX, frames...) 
//---------------------------------------------------------------------- 
try 
    {  
    bool        HasExternalContent = false; 
    DelphiInterface<IHTMLDocument2>  diDoc;        // Smart pointer wrapper - should automatically call release() and do reference counting 
    diDoc = TEmbeddedWB->Document; 

    DelphiInterface<IHTMLElementCollection>  diColApplets;   DelphiInterface<IDispatch>   diDispApplets;  DelphiInterface<IHTMLObjectElement> diObj; 
    DelphiInterface<IHTMLElementCollection>  diColEmbeds;   DelphiInterface<IDispatch>   diDispEmbeds; 
    DelphiInterface<IHTMLFramesCollection2>  diColFrames;   DelphiInterface<IDispatch>   diDispFrames; 
    DelphiInterface<IHTMLElementCollection>  diColImages;   DelphiInterface<IDispatch>   diDispImages;  DelphiInterface<IHTMLImgElement> diImg; 
    DelphiInterface<IHTMLElementCollection>  diColLinks;    DelphiInterface<IDispatch>   diDispLinks; 
    DelphiInterface<IHTMLElementCollection>  diColPlugins;   DelphiInterface<IDispatch>   diDispPlugins; 
    DelphiInterface<IHTMLElementCollection>  diColScripts;   DelphiInterface<IDispatch>   diDispScripts; 
    DelphiInterface<IHTMLStyleSheetsCollection> diColStyleSheets;  DelphiInterface<IDispatch>   diDispStyleSheets; 

    OleCheck(diDoc->Get_applets  (diColApplets)); 
    OleCheck(diDoc->Get_embeds  (diColEmbeds)); 
    OleCheck(diDoc->Get_frames  (diColFrames)); 
    OleCheck(diDoc->Get_images  (diColImages)); 
    OleCheck(diDoc->Get_links  (diColLinks)); 
    OleCheck(diDoc->Get_plugins  (diColPlugins)); 
    OleCheck(diDoc->Get_scripts  (diColScripts)); 
    OleCheck(diDoc->Get_styleSheets (diColStyleSheets)); 

    // Scan for applets external links 
    for (int i = 0; i < diColApplets->length; i++) 
     { 
     OleCheck(diColApplets->item(i,i,diDispApplets)); 
     if (diDispApplets != NULL) 
      { 
      diDispApplets->QueryInterface(IID_IHTMLObjectElement, (void**)&diObj); 
      if (diObj != NULL) 
       { 
       UnicodeString s1 = Sysutils::Trim(diObj->data), 
           s2 = Sysutils::Trim(diObj->codeBase), 
           s3 = Sysutils::Trim(diObj->classid); 

       if (StartsText("http", s1) || StartsText("http", s2) || StartsText("http", s3)) 
        { 
        HasExternalContent = true; 
        break;             // At least 1 found, bar will be shown, no further search needed 
        } 
       } 
      } 
     } 

    // Scan for images external links 
    for (int i = 0; i < diColImages->length; i++) 
     { 
     OleCheck(diColImages->item(i,i,diDispImages)); 
     if (diDispImages != NULL)           // Unnecessary? OleCheck throws exception if this applies? 
      { 
      diDispImages->QueryInterface(IID_IHTMLImgElement, (void**)&diImg); 
      if (diImg != NULL) 
       { 
       UnicodeString s1 = Sysutils::Trim(diImg->src); 

       // Case insensitive check 
       if (StartsText("http", s1)) 
        { 
        HasExternalContent = true; 
        break;             // At least 1 found, bar will be shown, no further search needed 
        } 
       } 
      } 
     } 
    } 
catch (Exception &e) 
    { 
    // triggered by OleCheck 
    ShowMessage(e.Message); 
    } 

有掃描此或只有一個更簡單的方法是使用其它接口功能,如Get_applets運行幾個循環,Get_embedsGet_stylesheets等類似上面的代碼到目前爲止,我發現我不得不調用以下功能涵蓋所有的這樣:

OleCheck(diDoc->Get_applets  (diColApplets)); 
    OleCheck(diDoc->Get_embeds  (diColEmbeds)); 
    OleCheck(diDoc->Get_frames  (diColFrames)); 
    OleCheck(diDoc->Get_images  (diColImages)); 
    OleCheck(diDoc->Get_links  (diColLinks)); 
    OleCheck(diDoc->Get_plugins  (diColPlugins)); 
    OleCheck(diDoc->Get_scripts  (diColScripts)); 
    OleCheck(diDoc->Get_styleSheets (diColStyleSheets)); 

但我寧願沒有實現,很多循環是否可以這樣處理更容易。它可以?

+0

句子*我想阻止任何從Internet加載的內容*表示您想要離線模式嗎?如果是這樣,只需將'TWebBrowser.Offline'設置爲True ;-) – TLama

+0

如果它非常簡單,那將會很棒。我設置了Offline和ForceOffline標誌,但它仍然會加載一些外部內容,例如[object]標籤或某些框架。 – Coder12345

+0

你的HTML有多複雜?你需要Internet Explorer嗎? – Pol

回答

2

我建議你這個解決方案:

#include "html.h" 
THTMLDocument doc; 
void __fastcall TForm1::CppWebBrowser1DocumentComplete(TObject *Sender, LPDISPATCH pDisp, 
      Variant *URL) 
{ 
    doc.documentFromVariant(CppWebBrowser1->Document); 

    bool HasExternalContent = false; 
    for (int i=0; i<doc.images.length; i++) { 
     if(doc.images[i].src.SubString(1, 4) == "http") 
     { 
      HasExternalContent = true; 
      break; 
     } 
    } 
    for (int i=0; i<doc.applets.length; i++) { 
     THTMLObjectElement obj = doc.applets[i]; 
     if(obj.data.SubString(1, 4) == "http") 
      HasExternalContent = true; 
     if(obj.codeBase.SubString(1, 4) == "http") 
      HasExternalContent = true; 
     if(obj.classid.SubString(1, 4) == "http") 
      HasExternalContent = true; 
    } 
} 

這馬麗娟包裝類可以從here下載。

+0

這看起來非常有用。這是什麼包裝?該網站或課堂本身沒有太多信息。 – Coder12345

+0

這個wapper自己編寫的應用程序有HTML UI或任何與HTML相關的組件。使用這個包裝器也可以處理C++ Builder中的html事件,比如「onmouseclick」;欲瞭解更多信息,請參閱[本](http://www.experts-exchange.com/Programming/Editors_IDEs/C_CPP_CS/CPP_Builder/A_4378-C-Builder-and-Dynamic-HTML.html)。 –