使用IE插件浏览器帮助程序对象(BHO)访问Frame或Iframe中的数据

Ken*_*h J 2 c# plugins internet-explorer dom bho

我正在编写一个IE插件,将电话号码包装在连接到电话系统的链接中,并在点击时拨打该号码.我通过使用DocumentComplete事件来完成此任务.

//using SHDocVw.WebBrowser
webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
Run Code Online (Sandbox Code Playgroud)

问题是我似乎无法访问框架和iframe元素内的元素.

问题:如何使用浏览器助手对象操纵IE中的框架和iframe元素内的数据?

Eri*_*Law 5

首先,一些警告.一般来说,这种性质的附加组件(例如,在所有页面上运行并扫描所有内容的附加组件)会对性能产生重大影响,并且可能导致用户在看到其带来的性能影响时删除或禁用该加载项.进一步看来,您在.NET中编写代码,由于性能影响,强烈建议不要这样做.

获取跨域子帧的内容并非易事,因为默认情况下您将获得拒绝访问.原因是,当您的加载项尝试获取跨域内容时,也会应用JavaScript存在的跨域安全限制.

要从顶级页面获取跨域内容,您必须跳过一些非常重要的环节,特别是在.NET中.你最好的办法是在每个框架的DocumentComplete事件上运行你的代码,正如杰夫观察到的那样.

如果您必须只从顶级页面运行一次代码,那么您可以使用以下技术执行此操作:

http://support.microsoft.com/default.aspx?scid=kb;en-us;196340

// &lpDocDisp is the dispatch pointer for the document
IHTMLDocument2* pDocument;
HRESULT hr = lpDocDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDocument);
if (FAILED(hr))
    return hr;

long iCount = 0;

// Now, check for subframes
// http://support.microsoft.com/default.aspx?scid=kb;en-us;196340
IOleContainer* pContainer;

// Get the container
hr = lpDocDisp->QueryInterface(IID_IOleContainer, (void**)&pContainer);
if (FAILED(hr) || (NULL == pContainer)){
    OutputDebugString("[AXHUNTER] Failed to get container\n");
    return hr;
}

LPENUMUNKNOWN  pEnumerator;

// Get an enumerator for the frames
hr = pContainer->EnumObjects(OLECONTF_EMBEDDINGS, &pEnumerator);
pContainer->Release();

if (FAILED(hr) || (NULL == pEnumerator)){
    OutputDebugString("[AXHUNTER] Failed to get enumerator\n");                 
    return hr;
}

IUnknown* pUnk;
ULONG uFetched;

// Enumerate all the frames
for (UINT i = 0; S_OK == pEnumerator->Next(1, &pUnk, &uFetched); i++)
{
    assert(NULL != pUnk);
    IWebBrowser2* pBrowser;
    hr = pUnk->QueryInterface(IID_IWebBrowser2, (void**)&pBrowser);
    pUnk->Release();

    if (SUCCEEDED(hr))
    {
        LPDISPATCH pSubDoc = NULL;
        hr = pBrowser->get_Document(&pSubDoc);
        if (SUCCEEDED(hr) && (NULL != pSubDoc)){
            CrawlPage(pSubDoc, ++iNested);
            pSubDoc->Release();
        }

        pBrowser->Release();
    }
    else
    {
        OutputDebugString("[AXHUNTER] Cannot get IWebBrowser2 interface\n");
    }
}


pEnumerator->Release();
Run Code Online (Sandbox Code Playgroud)

  • +1点好点.另请参阅http://social.msdn.microsoft.com/forums/en-US/winforms/thread/38126c55-bc55-40ae-9b42-3a2086341e4c上的.Net示例 (2认同)