4

TEmbeddedWB または TWebBrowser (または TCppWebBrowser) によってロードされた外部をブロックしようとしています。画像、javascript、外部 CSS、外部の [embed] または [object] または [applet] または [frame] または [iframe] を含むインターネットから読み込まれるもの、外部コンテンツを読み込むことができる JavaScript の実行などをブロックしたいと思います。

この問題は 2 つの部分で構成されています。

  • Web ブラウザを「すべて制限」(画像のない基本的な HTML を除く) に設定し、そのようなコンテンツが存在するかどうかを検出する
  • 外部コンテンツが存在しない場合は、「ダウンロード バー」が表示されます。クリックすると Web ブラウザが「すべてダウンロード」モードになり、すべてのコンテンツが取得されます。

最初のアイテムに問題があります。TEmbeddedWB では、DownloadOptions スイッチを使用してほとんどすべてをブロックできます。最も重要なのは ForceOffline スイッチですが、これらをすべてオフにしても、[object][iframe]タグなどを通過します。OnBeforeNavigate2 イベントを実装し、これらのタグに含まれる URL に対してトリガーし、ローカル サーバーのログにもエントリを作成するため、これが事実であることはわかっています。TEmbeddedWB を設定OfflineModeForceOfflineModeても、これらの項目には役に立ちません。

では、どうすれば本当にすべてをブロックできますか? そのため、スクリプトや CSS などのブロックされた外部要素を含む基本的な HTML として開始する必要があります。何かをダウンロードするたびにイベントをトリガーしてブロックしたり、すべての外部ダウンロードをブロックすることでそのようなイベントのトリガーを最初から回避したりする方法はありますか? Internet Explorer のゾーンとセキュリティをいじる必要はありますか? 正しい方向へのポインタは役に立ちます。

問題のあるタグ (「アプレット」、「スクリプト」、「リンク」など) が存在するかどうかを検出する必要があるため、2 番目の項目も注意が必要です。この検出は完全である必要はありませんが、少なくともカバーするには十分である必要がありますそのようなタグのほとんど. 私はこのようにそれをやった:

//----------------------------------------------------------------------
// 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));

しかし、これが簡単に処理できるのであれば、それほど多くのループを実装したくありません。それをできる?

4

1 に答える 1

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;
    }
}

この優れたラッパー クラスは、ここからダウンロードできます。

于 2012-05-18T06:15:24.400 に答える