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

标签 c# internet-explorer dom plugins bho

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

//using SHDocVw.WebBrowser
webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);

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

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

最佳答案

首先,有一些注意事项。一般来说,这种性质的附加组件(例如,在所有页面上运行并扫描所有内容的附加组件)会对性能产生重大影响,并且当用户看到附加组件所带来的性能影响时,可能会导致用户删除或禁用该附加组件。看来您正在使用 .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();

关于c# - 使用 IE 插件浏览器帮助程序对象 (BHO) 访问 Frame 或 Iframe 中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3508317/

相关文章:

internet-explorer - 避免 IE 中 http 和 https 弹出窗口冲突的最佳解决方案是什么?

html - 具有跨度的 anchor 不适用 :active effect on IE

javascript - 获取外部元素的html

javascript - 使单选按钮在加载表单时不被选中?

c# - MongoDB中的默认ObjectId

c# - 使用 javascript 填充标签值。回发后代码后面的标签为空?

css - 是否有修复 IE 渲染错误的 javascript 库?

javascript - 为什么 document.title 不适用于 SVG?

javascript - DOM 加载断点

c# - 如何使用 ElasticSearch 只返回属性的子集