【急】内嵌的iframe的ihtmldocument2获取到后访问数据出错解决方法
【急!!!】内嵌的iframe的ihtmldocument2获取到后访问数据出错
这个帖子已经解决了
【急】怎样根据iframe的name获取内嵌的iframe的ihtmldocument2?
http://topic.****.net/u/20110130/12/d00276b7-058f-4acc-a860-94df73f587cf.html
但是获取到的ihtmldocument2接口再获取ihtmlelement出错~ E_ACCESS_DENIED
------解决方案--------------------
一般来说是因为IE的安全限制引起的,有两种可能:
1) 你是不是跨线程使用的IHTMLDocument2
如果是这样,最简单的方法是你在线程中再去获取IHTMLDocument2,不要先获取了传到线程中用...
否则就需要列集COM对象
CoMarshalInterThreadInterfaceInStream()/CoGetInterfaceAndReleaseStream()
2) 你的iframe跨域了,为了避免这种情况下的XSS攻击,IE安全限制不允许你跨域操作。
不过跨域的时候在拿IHTMLDocument2应该就会出错。
这个页面上有跨域获取IHTMLDocument2的解决办法:
http://codecentrix.blogspot.com/2007/10/when-ihtmlwindow2getdocument-returns.html
这个帖子已经解决了
【急】怎样根据iframe的name获取内嵌的iframe的ihtmldocument2?
http://topic.****.net/u/20110130/12/d00276b7-058f-4acc-a860-94df73f587cf.html
但是获取到的ihtmldocument2接口再获取ihtmlelement出错~ E_ACCESS_DENIED
------解决方案--------------------
一般来说是因为IE的安全限制引起的,有两种可能:
1) 你是不是跨线程使用的IHTMLDocument2
如果是这样,最简单的方法是你在线程中再去获取IHTMLDocument2,不要先获取了传到线程中用...
否则就需要列集COM对象
CoMarshalInterThreadInterfaceInStream()/CoGetInterfaceAndReleaseStream()
2) 你的iframe跨域了,为了避免这种情况下的XSS攻击,IE安全限制不允许你跨域操作。
不过跨域的时候在拿IHTMLDocument2应该就会出错。
这个页面上有跨域获取IHTMLDocument2的解决办法:
http://codecentrix.blogspot.com/2007/10/when-ihtmlwindow2getdocument-returns.html
- C/C++ code
When IHTMLWindow2::get_document returns E_ACCESSDENIED Internet Explorer extensions usually needs to access HTML elements. When extensions are initialized they get a IWebBrowser2 pointer representing the browser. Starting with this pointer one can get any HTML element in the web page but to do that we need to browse a hierarchy of frames first. The simplest web pages only have one frame and one document. Web pages containing <frame> or <iframe> have a hierarchy of frames, each frame having its own document. Here are the objects involved and the corresponding interfaces: browser - IWebBrowser2 frame/iframe - IHTMLWindow2 document - IHTMLDocument2 element - IHTMLElement The list bellow shows what method to call to get one object from another: 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 A normal call chain to get a HTML element is: browser -> document -> frame -> child frame -> ... -> child frame -> document -> element This will work almost all the time. The problems arise when different frames contain documents loaded from different internet domains. In this case IHTMLWindow2::get_document returns E_ACCESSDENIED when trying to get the document from the frame object. I think this happens to prevent cross frame scripting atacks. Here is HtmlWindowToHtmlDocument function I wrote to be used instead IHTMLWindow2::get_document to bypass the restriction: // Converts a IHTMLWindow2 object to a IHTMLDocument2. Returns NULL in case of failure. // 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; }