C# 使用IE插件浏览器辅助对象(BHO)访问帧或Iframe中的数据

C# 使用IE插件浏览器辅助对象(BHO)访问帧或Iframe中的数据,c#,internet-explorer,dom,plugins,bho,C#,Internet Explorer,Dom,Plugins,Bho,我正在写一个IE插件,它将电话号码包装在一个链接中,连接到电话系统,点击后拨打该号码。我是通过使用DocumentComplete事件来实现这一点的 //using SHDocVw.WebBrowser webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete); 问题是我似乎无法访问frame和iframe元素内部的元素 问题:如何使用浏

我正在写一个IE插件,它将电话号码包装在一个链接中,连接到电话系统,点击后拨打该号码。我是通过使用DocumentComplete事件来实现这一点的

//using SHDocVw.WebBrowser
webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
问题是我似乎无法访问frame和iframe元素内部的元素


问题:如何使用浏览器辅助对象在IE中操作frame和iframe元素中的数据?

在iframe中操作数据时,我能想到的唯一方法是给它一个查询字符串,或者你可以做某种回发(可能是异步的?)。至于从该iframe中检索数据,将采用相同的方式。关于框架,据我所知,它们是不推荐使用的,因此我建议您考虑更改它们。

您不能在框架内走动,但DWebBrowserEvents2应该为每个框架触发一个文档完成事件。你只要把它们都记录下来就行了。不确定如何将其转换为托管代码


根据您的需求,只编写一个。它们只是IE8+,但是…

首先,有一些警告。一般来说,这种性质的加载项(例如,在所有页面上运行并扫描所有内容的加载项)会对性能产生重大影响,当用户看到加载项带来的性能影响时,可能会导致用户删除或禁用该加载项。此外,您似乎是在.NET中编写代码,由于性能的影响,这也是强烈反对的

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

要从顶级页面获取跨域内容,您必须跳过一些非常重要的障碍,尤其是在.NET中。正如Jeff所观察到的,最好的办法是在每个帧的DocumentComplete事件上运行代码

如果必须只从顶层页面运行代码一次,则可以使用以下技术:


要求是任何页面上的每个电话号码都必须是一个链接,可能会在某个地方显示所有找到的电话号码。我认为使用加速器是不可能的。实际上,我更喜欢使用加速器,因为它可以确保每个使用它的人都升级到IE8.+1很棒的分数。另外,请参见上的.Net示例
// &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();