使用IE插件浏览器帮助对象(BHO)访问iframe中的正文(至少一些数据) [英] Accessing body (at least some data) in a iframe with IE plugin Browser Helper Object (BHO)

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

问题描述

我正在开发 IE8 + BHO插件。现在我只是试图在另一个 iframe(id =canvas_frame)中包含的 iframe(class =Al Ai Editable) / p>

我设法获得了想要添加文本的iframe的 IHTMLElement (class =Al Ai editable)。我可以证明这一点的事实,el变量是类型IHTMLElement:

  el-> get_className(& cl ); // Al Ai editable 

正确显示MessageBox中的iframe类。



我现在的问题是我不能访问此相应iframe的正文元素



例如,当我尝试使用下面的代码访问iframe的主体时使用下面的代码,然后这会崩溃浏览器:

  el-> getElementById(L:d6,& el); //:d6是iframe中的主体的ID 

内部HTML或内部Text我只是得到一个空字符串:

  el-> get_innerHTML(& htm); 
MessageBox(hwnd,htm,LBHO cl,MB_OK);

  el-> get_innerText(& htm); 
MessageBox(hwnd,htm,LBHO cl,MB_OK);

不显示任何内容()。



我甚至尝试了 el-> get_children 方法,也没有帮助。



这是一个完整的函数:

  void CgmailAdderBHO :: checkIframes (HWND hwnd,IDispatch * lpDisp){

USES_CONVERSION;

if(lpDisp){
IOleContainer * pContainer;

//获取容器
HRESULT hr = lpDisp-> QueryInterface(IID_IOleContainer,
(void **)& pContainer);
lpDisp-> Release();

if(FAILED(hr)){
return;
}

IEnumUnknown * pEnumerator;

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

if(FAILED(hr)){
return;
}

IUnknown * pUnk;
ULONG uFetched;

//枚举并刷新所有框架
for(UINT i = 0; S_OK == pEnumerator-> Next(1,& pUnk,& uFetched); i ++)
{
IWebBrowser2 * pBrowser;

hr = pUnk-> QueryInterface(IID_IWebBrowser2,(void **)& pBrowser);
pUnk-&Release; Release();

if(SUCCEEDED(hr))
{
//处理iframe
CComPtr< IDispatch> docDisp;
pBrowser-> get_Document(& docDisp);
CComQIPtr< IHTMLDocument3> doc = docDisp;
CComQIPtr< IHTMLElementCollection> iframes;

HRESULT hr = doc-> getElementsByTagName(SysAllocString(Lbody),& iframes);
long length;
iframes-> get_length(& length);
CComVariant itemIndex(0);
CComVariant empty;
CComQIPtr< IDispatch> htmlEl;

iframes-> item(itemIndex,empty,& htmlEl);
CComQIPtr< IHTMLElement> el = htmlEl;
BSTR cl;
BSTR cln(LcP);
el-> get_className(& cl);

if(cl&& strcmp(OLE2A(cl),cP)== 0){
// this is the canvas_frame
// check if it有任何其他子帧
BSTR html;
el-> get_innerHTML(& html);

doc-> getElementsByTagName(SysAllocString(Liframe),& iframes);
if(iframes){
iframes-> get_length(& length);
if(length> 0){
// MessageBox(hwnd,LWe are on compose!,LBHO,MB_OK)
//此处添加加密按钮代码
iframes-> item(itemIndex,empty,& htmlEl);
el = htmlEl;
el-> get_className(& cl); // Al Ai editable

BSTR htm;
el-> get_innerHTML(& htm);
MessageBox(hwnd,cl,LBHO cl,MB_OK);
MessageBox(hwnd,htm,LBHO cl,MB_OK);

CComQIPtr< IHTMLDocument3> docul = htmlEl;

// docul-> getElementById(L:d6,& el);

break; // found iframe;现在退出
}
}
}
pBrowser-> Release();
}
}
pEnumerator-> Release();
}
}


解决方案

错误的原因是安全限制。您正在访问嵌套的iframe,因此您需要重新配置您的函数,以递归地绕过该限制。



查看如何使用

访问第一级iframe:

hr = pContainer- > EnumObjects(OLECONTF_EMBEDDINGS,& pEnumerator);



但使用

  doc-> getElementsByTagName(SysAllocString(Liframe),& iframes);'

以访问嵌套iframe?这是错误,您需要访问嵌套的iframe与第一个相同,使用EnumObjects然后获得IWebBrowser2接口。


I'm developing an IE8+ BHO plugin. For now I'm simply trying to insert a text into an iframe (class="Al Ai Editable") contained in another iframe (id="canvas_frame").

I managed to obtain the IHTMLElement of the iframe i want to add text to (the class="Al Ai editable"). I can prove this by the fact that the el variable which is of type IHTMLElement :

el->get_className(&cl); //Al Ai editable

is correctly displaying the class of the iframe in the MessageBox.

The problem i have now is that i can't access the body element of this respective iframe.

For example when i try to access the body of the iframe with its id using the following code then this crashes the browser:

el->getElementById(L":d6", &el); // ":d6" is the id of the body inside the iframe

Also, trying to obtain the inner HTML or inner Text i simply obtain an empty string:

el->get_innerHTML(&htm);
MessageBox(hwnd, htm, L"BHO cl", MB_OK);

or

el->get_innerText(&htm);
MessageBox(hwnd, htm, L"BHO cl", MB_OK);

displays nothing ("").

I've even tryed the el->get_children method and that didn't help either.

Here's a the whole function :

void CgmailAdderBHO::checkIframes(HWND hwnd, IDispatch *lpDisp) {

USES_CONVERSION;

if (lpDisp) {
    IOleContainer* pContainer;

    // Get the container
    HRESULT hr = lpDisp->QueryInterface(IID_IOleContainer,
                                       (void**)&pContainer);
    lpDisp->Release();

    if (FAILED(hr)) {
      return;
    }

   IEnumUnknown* pEnumerator;

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

   if (FAILED(hr)) {
      return;
   }

   IUnknown* pUnk;
   ULONG uFetched;

   // Enumerate and refresh all the frames
   for (UINT i = 0; S_OK == pEnumerator->Next(1, &pUnk, &uFetched); i++)
   {
      IWebBrowser2* pBrowser;

      hr = pUnk->QueryInterface(IID_IWebBrowser2, (void**)&pBrowser);
      pUnk->Release();

     if (SUCCEEDED(hr))
     {
         // process the iframe
         CComPtr<IDispatch> docDisp;
        pBrowser->get_Document(&docDisp);
        CComQIPtr<IHTMLDocument3> doc = docDisp;
        CComQIPtr<IHTMLElementCollection> iframes;

        HRESULT hr = doc->getElementsByTagName(SysAllocString(L"body"), &iframes);
        long length;
        iframes->get_length(&length);
        CComVariant itemIndex(0);
        CComVariant empty;
        CComQIPtr<IDispatch> htmlEl;

        iframes->item(itemIndex, empty, &htmlEl);
        CComQIPtr<IHTMLElement> el = htmlEl;
        BSTR cl;
        BSTR cln(L"cP");
        el->get_className(&cl);

        if (cl && strcmp(OLE2A(cl), "cP") == 0) {
            //this is the canvas_frame
            // check if it has any other subframes
            BSTR html;
            el->get_innerHTML(&html);

            doc->getElementsByTagName(SysAllocString(L"iframe"), &iframes);
            if (iframes) {
                iframes->get_length(&length);
                if (length > 0) {
                    //MessageBox(hwnd, L"We are on compose!", L"BHO", MB_OK);
                    //add encrypt button code here
                    iframes->item(itemIndex, empty, &htmlEl);
                    el = htmlEl;
                    el->get_className(&cl); //Al Ai editable

                    BSTR htm;
                    el->get_innerHTML(&htm);
                    MessageBox(hwnd, cl, L"BHO cl", MB_OK);
                    MessageBox(hwnd, htm, L"BHO cl", MB_OK);

                    CComQIPtr<IHTMLDocument3> docul = htmlEl;

                    //docul->getElementById(L":d6", &el);

                    break; // found iframe ; now exit for
                }
            }
        }
        pBrowser->Release();
      }
   }
   pEnumerator->Release();
}
}

解决方案

The reason for the error is a security restriction. You're accessing a nested iframe so you'll need to reconfigure your function to work recursively to bypass the restriction.

See how you access the first level of iframes using

hr = pContainer->EnumObjects(OLECONTF_EMBEDDINGS, &pEnumerator);

but then use

doc->getElementsByTagName(SysAllocString(L"iframe"), &iframes);'

to access the nested iframes ? That's the error, you need to access the nested iframes the same as the first ones, using EnumObjects and then getting the IWebBrowser2 interface.

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

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