获取IE (控件)的所有链接(包括Frameset, iframe)
获取IE (控件)的所有链接(包括Frameset, iframe)
IE 顶层 body 节点通过IHTMLElement->get_all 方法无法获取iframe 里面的节点列表
CComPtr<IDispatch> spDispCollection;
body->get_all(&spDispCollection);
所以要获取iframe/frame(frameset) 里面的节点列表的话, 则需要根据body/doc 找到frames, 然后从frames -> IHTMLWindow2 -> IHTMLDocument2 . 主要有2个方法, 下面是代码片段
方法一:
IHTMLWindow2 *pHTMLWnd = NULL;
IHTMLDocument2 *pFrameDoc=NULL;
IHTMLFramesCollection2 *pFramesCollection=NULL;
LPDISPATCH lpDispatch;
long p;
VARIANT varindex,varresult;
varresult.vt=VT_DISPATCH;
varindex.vt = VT_I4;
if(pDoc!=NULL)
{
HRESULT hr=pDoc->get_frames(&pFramesCollection);
if(SUCCEEDED(hr)&&pFramesCollection!=NULL)
{
hr=pFramesCollection->get_length(&p);
if(SUCCEEDED(hr))
for(int i=0; i<p; i++)
{
varindex.lVal = i;
if(pFramesCollection->item(&varindex, &varresult) ==S_OK)
{
lpDispatch=(LPDISPATCH)varresult.ppdispVal;
if (SUCCEEDED(lpDispatch->QueryInterface(IID_IHTMLWindow2, (LPVOID *)&pHTMLWnd)))
{
if(SUCCEEDED(pHTMLWnd->get_document( &pFrameDoc)))
{
//work with the pFrameDoc
}
pHTMLWnd->Release();
pHTMLWnd=NULL;
}
}
}
pFramesCollection->Release();
}
pDoc->Release();
}
方法二:
CComBSTR bstrTagName;
pElem->get_tagName(&bstrTagName);
if ( lstrcmpiW(L"IFRAME", bstrTagName)==0 ||
lstrcmpiW(L"FRAME", bstrTagName)==0 )
{
CComQIPtr<IHTMLFrameBase2> _framebase2;
CComPtr<IHTMLWindow2> _framewindow;
CComPtr<IHTMLDocument2> _framedoc;
if( (_framebase2 = spItem)
&& SUCCEEDED( _framebase2->get_contentWindow(&_framewindow) ) && _framewindow!=NULL
&& SUCCEEDED( _framewindow->get_document(&_framedoc) ) && _framedoc!=NULL )
{
// 对 _framedoc 节点进行处理
}
}
iframe 跨域访问(cross frame) zz from : http://codecentrix.blogspot.com/2007/10/when-ihtmlwindow2getdocument-returns.html
由于安全性限制, 为防止跨域脚本攻击, 当frames 跨域的时候, IHTMLWindow2::get_document 调用将返回 E_ACCESSDENIED .
下面函数 HtmlWindowToHtmlDocument 对于跨域的frame 通过 IHTMLWindow2 -> IID_IWebBrowserApp -> IHTMLWindow2 绕过了限制.
// It takes into account accessing the DOM across frames loaded from different domains.
CComQIPtr<IHTMLDocument2> HtmlWindowToHtmlDocument(CComQIPtr<IHTMLWindow2> spWindow)
{
ATLASSERT(spWindow != NULL);
CComQIPtr<IHTMLDocument2> spDocument;
HRESULT hRes = spWindow->get_document(&spDocument);
if ((S_OK == hRes) && (spDocument != NULL))
{
// The html document was properly retrieved.
return spDocument;
}
// hRes could be E_ACCESSDENIED that means a security restriction that
// prevents scripting across frames that loads documents from different internet domains.
CComQIPtr<IWebBrowser2> spBrws = HtmlWindowToHtmlWebBrowser(spWindow);
if (spBrws == NULL)
{
return CComQIPtr<IHTMLDocument2>();
}
// Get the document object from the IWebBrowser2 object.
CComQIPtr<IDispatch> spDisp;
hRes = spBrws->get_Document(&spDisp);
spDocument = spDisp;
return spDocument;
}
// Converts a IHTMLWindow2 object to a IWebBrowser2. Returns NULL in case of failure.
CComQIPtr<IWebBrowser2> HtmlWindowToHtmlWebBrowser(CComQIPtr<IHTMLWindow2> spWindow)
{
ATLASSERT(spWindow != NULL);
CComQIPtr<IServiceProvider> spServiceProvider = spWindow;
if (spServiceProvider == NULL)
{
return CComQIPtr<IWebBrowser2>();
}
CComQIPtr<IWebBrowser2> spWebBrws;
HRESULT hRes = spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&spWebBrws);
if (hRes != S_OK)
{
return CComQIPtr<IWebBrowser2>();
}
return spWebBrws;
}
附:
IE(控件/接口)中主要有4个部分, Browser, Document, Frame/IFrame, Element , 其对应接口分别是
Browser - IWebBrowser2
Document - IHTMLDocument2
Frame/IFrame- IHTMLWindow2
Element - IHTMLElement
可以通过下面方法互相获取
browser -> document IWebBrowser2::get_Document
document -> frame IHTMLDocument2::get_parentWindow
frame -> document IHTMLWindow2::get_document
frame -> parent frame IHTMLWindow2::get_parent
frame -> children frames IHTMLWindow2::get_frames
element -> Frame IHTMLElement->QI(IHTMLFrameBase2) -> IHTMLFrameBase2->get_contentWindow -> IHTMLWindow2
ref:
在多Frame的网页中怎么取出各个Frame的IHTMLDocument2的接口!急用.(高分)
在文章 When IHTMLWindow2::get_document returns E_ACCESSDENIED 解决了iframe 跨域访问的问题
posted on 2008-07-30 19:17 泡泡牛 阅读(5153) 评论(3) 编辑 收藏 引用 所属分类: Develop
获取IE (控件)的所有链接(包括Frameset, iframe)的更多相关文章
- WPF获取原始控件样式。
要获取WPF控件的原始样式,需要我们安装Blend for Visual Studio. 然后,我们打开Blend for Visual Studio,创建一个WPF项目. 然后,我们向页面拖动一个B ...
- Selenium IDE安装和检查获取的控件路径技巧
来源:http://www.jianshu.com/p/0ea2dc83549f 从学习Selenium 开始,都是自己写脚本,后来得知有个插件Selenium IDE可以录制脚本,也懒得用了,觉得自 ...
- UGUI 之获取当前控件的高度
当Canvas Scaler选择Constant Pixel Size 当前的分辨率会被被固定,可以用RectTransform类里面的.rect变量值获取 height或Width. 在次情况下获取 ...
- winfrom获取用户控件里的控件对象
如何获取用户控件里的控件对象呢,其实思路也是很简单的, 比如有一个panel 用户控件 里面有许多的其他控件. 那么要找出一个Label控件怎么找呢,好的.现在我们就开始 首先,一个foreach循环 ...
- 获取android控件的高度
问题 如何获取一个控件的长和高,相信很多朋友第一眼看见这个问题都会觉得很简单,直接在onCreate里面调用getWidth.getMeasuredWidth不就可以获得了吗,但是,事实上是并没有简单 ...
- .net获取select控件中的文本内容
.net获取select控件中的文本内容 2009-11-28 21:19小V古 | 分类:C#/.NET | 浏览1374次 <select id="SecType" st ...
- JS获取用户控件中的子控件Id
用户控件 <asp:HiddenField ID="hfGradeId" runat="server" /> <asp:HiddenField ...
- 获取Repeater控件中的每一项数据
var items = rptList.Items;//获取Repeater控件的所有项 foreach (RepeaterItem item in items)//遍历每一项内容 { var t ...
- JS 获取Button控件的提交类型
<script type="text/javascript"> <!--获取button控件的类型---> function isAuditOrCancel ...
随机推荐
- 假设A.jsp内设定一个<jsp:useBean>元素:
假设A.jsp内设定一个<jsp:useBean>元素: <jsp:useBean id=”bean1” class=”myBean” /> 下列哪一个为真?(选择1项) A. ...
- jquery -- body div 和 body>div 的区别
body div表示body下的所有div标签都应用样式,不管是body的儿子还是孙子或更孙子 body >div表示只有body的儿子div才应用样式,孙子以后都不应用
- js调绝对定位的top
$("ggg div").each(function () { this.style.top = (parseFloat(this.style.top ...
- jconsole监控tomcat
一.专业术语 GC垃圾回收机制:当需要分配的内存空间不再使用的时候,JVM将调用垃圾回收机制来回收内存空间. JMX(Java Management Extensions,即Java管理扩展)是一个为 ...
- Hibernate_day01--Hibernate配置文件详解_核心api
Hibernate映射配置文件(重点) 1 映射配置文件名称和位置没有固定要求 2 映射配置文件中,标签name属性值写实体类相关内容 (1)class标签name属性值实体类全路径 (2)id标签和 ...
- Fel初认识
Fel在源自于企业项目,设计目标是为了满足不断变化的功能需求和性能需求. Fel是开放的,引擎执行中的多个模块都可以扩展或替换.Fel的执行主要是通过函数实现,运算符(+.-等都是Fel函数),所有这 ...
- m2014-software->Word2010发布博客文章至Cnblogs
转自:http://www.cnblogs.com/xfiver/archive/2011/12/26/2301591.html 昨夜喝醉,今天早起梳理情绪,看下如何使用word2010直接写cnbl ...
- 在Hyper-V Linux VM如何选择LIS Linux集成服务
导读 很多工程师都知道,如果你选择在 Hyper-V 中运行 Linux guest VM,要获得最好的使用体验,必需针对你所使用的 Linux 发行版和使用场景选择 Linux Integratio ...
- 网络代理-Firefox在shadow socks下面的使用
好久不写了,嘿嘿,中午好哈大家,给大家介绍下firefox下配置shadowsocks使用代理. 第一步:先下载一个firefox. 第二步: 打开设置 找到组件选项. 3.第三步: 4.第四步: 5 ...
- Objective-C入门教材
2011-05-11 15:58 三聪 cnblogs 字号:T | T 阅读本文前,你也要了解面向对象的基本概念.对象的使用以及面象对象设计模式都是bjective-C进行面向对象编程和设计Coco ...