我正在编写一个 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/