使用 IE 插件 Browser Helper Object (BHO) 在 iframe 中访问正文(至少一些数据)

Posted

技术标签:

【中文标题】使用 IE 插件 Browser Helper Object (BHO) 在 iframe 中访问正文(至少一些数据)【英文标题】:Accessing body (at least some data) in a iframe with IE plugin Browser Helper Object (BHO) 【发布时间】:2011-07-04 10:11:11 【问题描述】:

我正在开发一个 IE8+ BHO 插件。现在,我只是尝试将文本插入另一个 iframe (id="canvas_frame") 中包含的 iframe (class="Al Ai Editable")

我设法获得了要添加文本的 iframe 的 IHTMLElement(class="Al Ai editable")。我可以通过 el 类型为 IhtmlElement 的变量来证明这一点:

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

在 MessageBox 中正确显示 iframe 的类。

我现在遇到的问题是我无法访问相应 iframe 的 body 元素

例如,当我尝试使用以下代码访问 iframe 的主体及其 id 时,浏览器会崩溃:

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

另外,尝试获取内部 HTML 或内部文本我只需获取一个空字符串:

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

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

什么都不显示(“”)。

我什至尝试过 el->get_children 方法,但也没有用。

这是一个完整的功能:

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


【问题讨论】:

这看起来可能会有所帮助。 ***.com/questions/3508317/… 在您的示例代码中,您将 SysAllocString 作为函数参数传递。这将导致内存泄漏,因为对 SysAllocString 的每次调用都需要对 SysFreeString 进行相应的调用。由于您使用的是 COM 类,因此请使用 CComBSTR 类。 【参考方案1】:

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

了解如何使用

访问第一级 iframe

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

然后使用

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

访问嵌套的 iframe ?这就是错误,您需要像第一个一样访问嵌套的 iframe,使用 EnumObjects 然后获取 IWebBrowser2 接口。

【讨论】:

以上是关于使用 IE 插件 Browser Helper Object (BHO) 在 iframe 中访问正文(至少一些数据)的主要内容,如果未能解决你的问题,请参考以下文章

(浏览器选项卡)Browser Tab

JS鼠标事件大全

使用datepicker和uploadify的冲突解决(IE双击才能打开附件上传对话框)

JQuery Draggable with hover + custom helper 区别(IE vs Chrome)

idea使用Maven Helper插件排除依赖冲突

如何将 FEATURE_BROWSER_EMULATION 设置为 IE8 模式?