使用IE插件浏览器辅助对象(BHO)访问Frame或Iframe中的数据 [英] Accessing data in a Frame or Iframe with IE plugin Browser Helper Object (BHO)

查看:400
本文介绍了使用IE插件浏览器辅助对象(BHO)访问Frame或Iframe中的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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



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

解决方案

首先,一些注意事项。一般来说,这种附加功能(例如在所有页面上运行并扫描所有内容的附件)具有重大的性能影响,并且可能导致用户在看到其所带来的性能影响时删除或禁用附加组件。进一步看来,您正在.NET中编写代码,这也是因为性能影响而强烈反对的。



获取跨域子帧的内容是因为默认情况下您将获得访问被拒绝。原因是当您的附加组件尝试获取跨域内容时,也会应用JavaScript中存在的跨域安全限制。



要获取交叉 - 从顶级页面的域内容,你必须跳过一些不平凡的环,尤其是在.NET中。你最好的办法是在每个框架的DocumentComplete事件上运行代码,如Jeff所观察到的那样。



如果你必须运行一次代码,从顶级页面,那么你可以用这样的技术:



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

  //& lpDocDisp是文档的调度指针
IHTMLDocument2 * pDocument;
HRESULT hr = lpDocDisp-> QueryInterface(IID_IHTMLDocument2,(void **)& pDocument);
if(FAILED(hr))
return hr;

long iCount = 0;

//现在检查子框架
// http://support.microsoft.com/default.aspx?scid=kb;en-us;196340
IOleContainer * pContainer;

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

LPENUMUNKNOWN pEnumerator;

//获取框架的枚举器
hr = pContainer-> EnumObjects(OLECONTF_EMBEDDINGS,& pEnumerator);
pContainer-> Release();

if(FAILED(hr)||(NULL == pEnumerator)){
OutputDebugString([AXHUNTER]无法获取枚举器\
return hr;
}

IUnknown * pUnk;
ULONG uFetched;

//枚举所有框架
(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]无法获取IWebBrowser2 interface\\\
);
}
}


pEnumerator-> Release();


I am writing an IE plugin that wrap phone numbers in a link that connects to a phone system and dials that number when clicked. I am accomplishing this by using DocumentComplete event.

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

The problem is I cannot seem to access elements inside of frame and iframe elements.

Question: How do you manipulate data inside frame and iframe elements in IE using a Browser Helper Object?

解决方案

First, some caveats. Generally speaking, add-ons of this nature (e.g. those that run on all pages and scan all content) have a major performance impact and are likely to result in users removing or disabling the add-on when they see the performance impact it entails. It further appears that you're writing your code in .NET, which is also strongly discouraged due to the performance impact.

Getting the contents of a cross-domain subframe is non-trivial because you will get an Access Denied by default. The reason is that the cross-domain security restriction that exists for JavaScript is also applied when your add-on attempts to get the cross-domain content.

To get the cross-domain content from the top-level page, you must jump through some hoops which are non-trivial, particularly in .NET. Your best bet is to just run your code on each frame's DocumentComplete event, as Jeff observed.

If you must run your code only once, from the top-level page, then you can do so with a technique like this one:

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

这篇关于使用IE插件浏览器辅助对象(BHO)访问Frame或Iframe中的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆