为何IE的iFrame无法通过get_Document获得IHTMLDocument2
hr错误是E_ACCESSDENIED,我测试过很多页面,发现有的页面可以的,但是有的页面不行,sina网的主页面有三个iFrame,3个是同样的结果(我通过主IHTMLDocument2接口获得Frames然后再通过每个Frame获取IHTMLWindow2,最后通过IHTMLWindow2的get_Document企图获得IHTMLDocument2)
问题点数:200、回复次数:17Top
1 楼congling(congling)回复于 2002-06-13 11:43:55 得分 0
源代码如下
void EnumFrame(CComPtr<IHTMLDocument2>& spDoc,int indent)
{
CComPtr<IHTMLFramesCollection2> spFrameCol;
HRESULT hr;
long count,i;
if(FAILED(spDoc->get_frames(&spFrameCol))) return;
if(FAILED(spFrameCol->get_length(&count))) return;
VARIANT varIndex,varDisp;
VariantInit(&varIndex);
VariantInit(&varDisp);
varIndex.vt=VT_I4;
for(i=0;i<count;i++)
{
CComPtr<IHTMLWindow2> spWin;
CComPtr<IHTMLDocument2> spChildDoc;
varIndex.lVal=i;
if(SUCCEEDED(spFrameCol->item(&varIndex,&varDisp)) && varDisp.vt==VT_DISPATCH)
{
if(SUCCEEDED(hr=varDisp.pdispVal->QueryInterface(IID_IHTMLWindow2,(void**)&spWin)))
{
if(SUCCEEDED(hr=spWin->get_document(&spChildDoc)))
{
CComBSTR bstrName;
if(SUCCEEDED(spWin->get_name(&bstrName)))
{
USES_CONVERSION;
char psz[100],*p;
memset(psz,' ',indent*3);
psz[indent*3]=0;
p=W2A(bstrName);
OutputDebugString(psz);
OutputDebugString(p);
OutputDebugString("\r\n");
}
EnumFrame(spChildDoc,indent+1);
}
}
}
VariantClear(&varDisp);
}
}
Top
2 楼ndugu()回复于 2002-06-13 11:56:32 得分 200
我的可以,你试试:
void CTryView::OnDocumentComplete(LPCTSTR lpszURL)
{
// TODO: Add your specialized code here and/or call the base class
IHTMLDocument2 * pDoc = NULL;
IHTMLWindow2 *pHTMLWnd = NULL;
IHTMLDocument2 * pFrameDoc=NULL;
IHTMLFramesCollection2 *pFramesCollection=NULL;
LPDISPATCH lpDispatch;
long p;
VARIANT varindex,varresult;
varresult.vt=VT_DISPATCH;
varindex.vt = VT_I4;
try
{
pDoc = (IHTMLDocument2*)(GetHtmlDocument());
if(pDoc!=NULL)
{
pDoc->get_frames(&pFramesCollection);
if(pFramesCollection!=NULL)
{
pFramesCollection->get_length(&p);
if(p>0)
{
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)))
{
CString info;
info.Format("%d",pFrameDoc);
MessageBox(info);
pFrameDoc->Release();
pFrameDoc=NULL;
}
pHTMLWnd->Release();
pHTMLWnd=NULL;
}
}
}
}
}
}
}
catch(...)
{
};
try
{
if(pDoc != NULL)
pDoc->Release();
if(pFramesCollection != NULL)
pFramesCollection->Release();
}
catch(...)
{
};
CHtmlView::OnDocumentComplete(lpszURL);
}Top
3 楼congling(congling)回复于 2002-06-13 12:31:07 得分 0
你的代码是在同一个进程中的,HTMLView中使用了WebBrowser的控件,看来这个问题可能是安全性的问题。你能在远进程中(就是IE进程)调用成功吗?
Top
4 楼congling(congling)回复于 2002-06-13 12:46:44 得分 0
慢!我用你的代码在CHTMLView中也作了测试,发现也不行!你有没有对新浪网的主叶面进行过测试?我发现这种方法对于一般的iFrame是可以的,但是对于Sina,好像就是不行.
下面这个叶面就是测试成功的叶面
<html>
<iframe name="iTestFrame" src="Test.html">hello world</iframe>
</html>Top
5 楼congling(congling)回复于 2002-06-13 14:35:58 得分 0
UpTop
6 楼ndugu()回复于 2002-06-13 16:58:18 得分 0
我试过是可以的,sina上有两个iframe,我测试时成功弹出两个对话框显示了
pFrameDoc地址。
另外,从你反应的错误来看,可能是接口指针释放不当导致的,与安全性无关,对ie也是一样。Top
7 楼chenybin(小马)回复于 2002-06-13 18:44:03 得分 0
算了
我来UP吧Top
8 楼daehappy(追求120%结贴)回复于 2002-06-13 21:45:24 得分 0
up!关注!Top
9 楼jiangsheng(蒋晟.Net[MVP])回复于 2002-06-13 21:54:36 得分 0
取得文档的方法依赖于IE的版本。高版本的IE(记得好像是5.5以上)要通过IHtmlFrameBase2接口访问。低版本的通过IHtmlWindow2访问。Top
10 楼congling(congling)回复于 2002-06-14 02:21:20 得分 0
这个问题我在MSDN上查找了一下,的确是一个安全问题(不同域的/不同URL类型的),解决的方法
1.(MSDN提供的解决方案)在相互交互的叶面中加上document.domain="xxxx";//xxx指的是相同的域名,但是这个方案显然在我的程序中不可行
2.可能要通过替换默认的URLMon的IInternetSecurityManager的接口来解决。这个IInternetSecurityManager我可以使用QueryInterface获得,不过要替换这个接口可能不是一件简单的事情
其实不但是iFrame甚至连Frame也会有问题:
以下的javascript代码也会同样的错误:
这个是在 http://congling.com/frame.html的叶面
<html>
<iframe name="iTestFrame" src="http://localhost:8080/frameset.html">hello world</iframe>
<script language=javascript>
function Show()
{
alert(document.frames.iTestFrame.document.all.length);
//alert(document.location.href);
}
</script>
<input type=button onclick="javascript:Show()" value="Show Info"> </html>
Reference:
Q167796 PRB: Permission Denied When Scripting Across Frames
Top
11 楼congling(congling)回复于 2002-06-14 02:37:38 得分 0
to ndugu:
在我这里你的方法的确不行,就是在
if(SUCCEEDED(hr=pHTMLWnd->get_document( &pFrameDoc)))错误,错误代码是: E_ACCESSDENIED,当时两个iFrame的域是sina.allyes.com以及2002.sina.com.cn
我不知道你那里为什么可以
Top
12 楼ndugu()回复于 2002-06-14 09:37:11 得分 0
我觉得蒋晟说的对,确实和IE的版本有关,但高版本不是一定要通过
IHtmlFrameBase2接口访问 ,我用的就是IE6,winxp。
另外顺便说一句,sina首页太龌龊了,在winme下会不断开新窗口和广告,
我这段代码在ie5.5下访问它时不行了,但也没出错呀。Top
13 楼ndugu()回复于 2002-06-14 09:53:37 得分 0
我觉得蒋晟说的对,这确实和ie版本有关系,但高版本ie并不一定要通过IHtmlFrameBase2接口访问,我就是在winxp、ie6下测试成功的。
另外顺便说一句,新浪的首页是在太龌龊了,在winme下会不断的开新窗口打
开主页和广告,我的方法在ie5.5下不行了。Top
14 楼ndugu()回复于 2002-06-14 09:58:03 得分 0
忘了说了:但是并没有出错。
其实这段代码我用在我的一个浏览器里,要求用户必须安装ie5.0以上,好像
访问别的网页都没有问题嘛。Top
15 楼congling(congling)回复于 2002-06-14 12:05:51 得分 0
那真是奇怪了,我这里安装的也是WinXp-Home edition,是原配的,而且带的也是IE6.0,我已经把所有的Patch/Windows Update都安装了,还是这样,很奇怪你那里为什么可以,你能把你的测试程序发给我吗?
另,你能看看上面的一段Javascript在你那里测试一把吗?我这儿所有的机器都不行。都是Access Denied的错误。
Email: congling@21cn.comTop
16 楼congling(congling)回复于 2002-06-14 12:10:12 得分 0
你指的不出错其实并非如此,你在VS的Output window可以明显的看到有First-Exception的错误,其实错误在IE控件内被的SEH异常处理了,因此表象上是没有错误的,但是你的对话框(MessageBox)是无法弹出来的。
Top
17 楼congling(congling)回复于 2002-06-15 13:40:52 得分 0
这个问题的确是安全问题。
但是这个问题没解决的同时我却遭受了病毒的洗礼,真背Top



