1. webBrowser1.Document.Window.Frames[0].Document”引发了“System.UnauthorizedAccessException”类型的异常 System.Windows.Forms.HtmlDocument {System.UnauthorizedAccessException}    
  2.   
  3. {"拒绝访问。 (异常来自 HRESULT:0x80070005 (E_ACCESSDENIED))"} System.SystemException {System.UnauthorizedAccessException}  
webBrowser1.Document.Window.Frames[0].Document”引发了“System.UnauthorizedAccessException”类型的异常 System.Windows.Forms.HtmlDocument {System.UnauthorizedAccessException} 

{"拒绝访问。 (异常来自 HRESULT:0x80070005 (E_ACCESSDENIED))"} System.SystemException {System.UnauthorizedAccessException}

最近这个跨域的安全问题很困扰,搞了好久,终于在朋友的帮助下找到了一个C++的方法HtmlWindowToHtmlWebBrowser

  1. CComPtr<IWebBrowser2> CTimerSerachDlg::HtmlWindowToHtmlWebBrowser(CComPtr<IHTMLWindow2> spWindow)   
  2. {   
  3.     ATLASSERT(spWindow != NULL);   
  4.     CComQIPtr<IServiceProvider>  spServiceProvider = spWindow;   
  5.     if (spServiceProvider == NULL)   
  6.     {   
  7.         return CComPtr<IWebBrowser2>();   
  8.     }   
  9.     CComPtr<IWebBrowser2> spWebBrws;   
  10.     HRESULT hRes = spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&spWebBrws);   
  11.     if (hRes != S_OK)   
  12.     {   
  13.         return CComPtr<IWebBrowser2>();   
  14.     }   
  15.     return spWebBrws;   
  16. }   
  17.   
  18. // Converts a IHTMLWindow2 object to a IHTMLDocument2. Returns NULL in case of failure.   
  19. // It takes into account accessing the DOM across frames loaded from different domains.   
  20. CComPtr<IHTMLDocument2> CTimerSerachDlg::HtmlWindowToHtmlDocument(CComPtr<IHTMLWindow2> spWindow)   
  21. {   
  22.     ATLASSERT(spWindow != NULL);   
  23.     CComPtr<IHTMLDocument2> spDocument;   
  24.     HRESULT hRes = spWindow->get_document(&spDocument);   
  25.     if ((S_OK == hRes) && (spDocument != NULL))   
  26.     {   
  27.         // The html document was properly retrieved.   
  28.         return spDocument;   
  29.     }   
  30.     // hRes could be E_ACCESSDENIED that means a security restriction that   
  31.     // prevents scripting across frames that loads documents from different internet domains.   
  32.     CComPtr<IWebBrowser2>  spBrws = HtmlWindowToHtmlWebBrowser(spWindow);   
  33.     if (spBrws == NULL)   
  34.     {   
  35.         return CComPtr<IHTMLDocument2>();   
  36.     }   
  37.     // Get the document object from the IWebBrowser2 object.   
  38.     CComPtr<IDispatch> spDisp;     hRes = spBrws->get_Document(&spDisp);   
  39.     spDocument = spDisp;   
  40.     return spDocument;   
  41. }  
CComPtr<IWebBrowser2> CTimerSerachDlg::HtmlWindowToHtmlWebBrowser(CComPtr<IHTMLWindow2> spWindow)
{
    ATLASSERT(spWindow != NULL);
    CComQIPtr<IServiceProvider>  spServiceProvider = spWindow;
    if (spServiceProvider == NULL)
    {
        return CComPtr<IWebBrowser2>();
    }
    CComPtr<IWebBrowser2> spWebBrws;
    HRESULT hRes = spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&spWebBrws);
    if (hRes != S_OK)
    {
        return CComPtr<IWebBrowser2>();
    }
    return spWebBrws;
}

// 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.
CComPtr<IHTMLDocument2> CTimerSerachDlg::HtmlWindowToHtmlDocument(CComPtr<IHTMLWindow2> spWindow)
{
    ATLASSERT(spWindow != NULL);
    CComPtr<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.
    CComPtr<IWebBrowser2>  spBrws = HtmlWindowToHtmlWebBrowser(spWindow);
    if (spBrws == NULL)
    {
        return CComPtr<IHTMLDocument2>();
    }
    // Get the document object from the IWebBrowser2 object.
    CComPtr<IDispatch> spDisp;     hRes = spBrws->get_Document(&spDisp);
    spDocument = spDisp;
    return spDocument;
}

在后来找到了作者的Blog,但是国内屏蔽了blogspot,直接不能够访问。

然后发现了作者的另外一篇文章:http://codecentrix.blogspot.com/2008/02/when-ihtmlwindow2document-throws.html

C# 跨域访问iframe的办法:http://www.codecentrix.com/blog/wnd2doc_csharp/GetDocumentFromWindowCsharp.zip

  1. IHTMLWindow2 htmlWindow = (IHTMLWindow2)(((HTMLDocumentClass)(webBrowser1.Document.DomDocument)).frames.item(ref index));   
  2. label1.Text = CodecentrixSample.CrossFrameIE.GetDocumentFromWindow(htmlWindow).activeElement.innerHTML;