如何访问 IHTMLDocument2 中不同域名下拒绝访问的 frames 对象 -- COM ERROR_(E_ACCESSDENIED)

两年半以前面试重庆某公司,她的主要产品产品为.NET开发的BI 和 C++开发的游戏. 本来面试的游戏设计,但未通过.正好朋友负责公司的测试部门管理并需要开发自动化测试工具,询问我是否有意. 偶辞职在家的几个月四处徒步旅游,玩,吃喝,钱包瘪了:) 加待遇在重庆来说也还可以就答应下来,这里要感谢朋友Crunch和公司给予的机会.
    
    要实现 WEB 应用程序自动化测试,可以通过记录 http 请求并重放和统计各种指标来实现,也可以象 WIN32 应用一样捕获相应的 html element 产生相应事件来实现.自动化测试可以减轻测试部门的工作压力.

    下面说说捕获 html element 和问题    
    捕获可见的 Microsoft Explorer (IE) 组件可以用以下方法:
    得到当前窗口句柄,并向此窗口发送 WM_HTML_GETOBJECT 消息, IE会返回 IHTMLDocument2 COM 指针到发送者. 有了 IHTMLDcoument2 指针,我们就可以做很多事情,如模拟 Document 对象中一个子对象的鼠标按下操作,还可以检测到是 Document 中子对象是否是我们所需要的值.甚至可以捕获 IE 的HTTP 请求.如今已离开这个公司, 前段时间在MSN上碰到以前公司的同事, 谈起不同域名下拒绝访问 frames 对象的问题,并想有解决办法.

    问题:
    当 Document 对象中包含多个 frames 的时候,直接通过 IHTMLDocument2.frames 或者 IHTMLFrameBase 或者 IHTMLWindow2 都不能访问不同不同域名下 frame 对象. 这个看起来是乎可以防止恶意的网站行为.但对我们测试也带来麻烦.

    解决问题的方法其实很简单,如下:
        
    (这个方法来源于国外的一个开发者论坛,解答者只是给出了微软关于获得HTML文档框架的连接 (见附录),没有其他的说明,我找不到那个地址了,不好意思.)

    我们知道通过 IHTMLDcoument2 对象可以得到 IContainer 对象, 而 IContainer 对象包含当前 HTMLDocument2 对象中所有子对象的 IWebBrowser2 对象,访问 IWebBrowser2 对象中 IHTMLDocument2 对象就是我们需要的 frame 对象包含的 IHTMLDocument2 对象. 那么对于每个子 IWebBrowser2 对象如何判断它属于哪个 frame 呢? 只需要比较 IHTMLFrameBase 和子 IWebBrowser2 对象的 IUnknown 指针地址是否相等就可以了.
    
    上面的叙述有些复杂,可用 C# 描述获得第一个子 IHTMLDocument2 对象,如下:    
     
    输入参数为当前 Document, 和 Document 中所有的 frame 的 IHTMLFrameBase2 对象.

  

    
    IHTMLDocument2 GetSubFrameDocument2 (IHTMLDocument2 Document2Base, ArrayList FrameBaseList)
    {    
        
object Unknown;
        
uint   fetched;

        IContainer Container    
= Document2Base as IContainer;
        
if (null == Container)
        {
            
// 错误处理
            
// ......
            
// ...
            return null;
        }

        IEnumUnknown Enumerator 
= Container as IEnumUnknown;
        
if (null == Enumerator)
        {
            
// 错误处理
            
// ......
            
// ...
            return null;
        }

        Enumerator.RemoteNext (
1out Unknown, out fetched);

        
if (null == Unknown) return null// 没有子对象
    
        IWebBrowser2 Browser2 
= Unknown as IWebBrowser2;
        
if (null == Browser2)
        {
            
// 错误处理
            
// ......
            
// ...
            return null;
        }
    
        
foreach (IHTMLFrameBase2 FrameMember in FrameBaseList)
        {
            
if (FrameMember == (Browser2 as IHTMLFrameBase2))         
            {
                
// 找到匹配子对象
                return Browser2.document as IHTMLDocument2;
            }                
        }  

        
return null;  
    }

    如果您使用其他编程语言稍微修改即可.

    附录:
    
    微软关于获得HTML文档框架的连接 
    http://support.microsoft.com/kb/196340

    我的资源中有一个HTML 组件捕获工具可以下载

    源码

   另: SharpDevelop 真是个好C#开源开发工具,谢谢

posted on 2011-11-30 13:37  缘从心开始  阅读(619)  评论(0编辑  收藏  举报

导航

文章作者:(Super)
文章出处:http://www.cnblogs.com/superai
欢迎转载,转载时请注明出处。谢谢合作。