webbrowser获取跨域的sessionStorage的值和cookie的值
2014-06-15 10:04
302 查看
这是个很麻烦的问题。
我需要用webbrowser获取一个iframe中的sessionStorage值,而这个iframe是跟原页面存在跨域问题的。
最初我打算使用HtmlDocument的InvokeScript,究其原因是execScript不支持返回值。既然需要调用脚本,则我首先得要注入这段脚本。
然后再调用invokeScript拿到脚本
既然如此,能否在调用webbrowser的代码中解决这个问题呢?早有人想到并解决了,跟COM交互并解决这个跨域问题
代码可以自行修正,但是最终obj就是我们想要的值
另一个问题是如何获取cookie,一般cookie获取其实比较容易
webbrowser的几个帖子
http://www.cnblogs.com/txw1958/archive/2012/09/24/CSharp-WebBrowser.html http://blog.csdn.net/jintougao/article/details/12948633 http://www.cnblogs.com/peterzb/archive/2009/07/12/1521787.html
我需要用webbrowser获取一个iframe中的sessionStorage值,而这个iframe是跟原页面存在跨域问题的。
最初我打算使用HtmlDocument的InvokeScript,究其原因是execScript不支持返回值。既然需要调用脚本,则我首先得要注入这段脚本。
HtmlDocument doc = this.webbrowser.Document.Window.Frames["frame1"].Frames["frame2"].Document; HtmlElement ele = doc.CreateElement("script"); ele.SetAttribute("type", "text/javascript"); ele.SetAttribute("text", "function test(){return window.sessionStorage[sensitiveData];}"); this.webbrowser.Document.Body.AppendChild(ele);
然后再调用invokeScript拿到脚本
this.webbrowser.Document.InvokeScript("test");对付无跨域的问题,以上的代码已经可以完成任务了,但偏偏我遇到的就是有跨域的问题,上面代码中frame1和frame2就分别在http和https下。我尝试着在chrome和ie中执行js脚本试图拿到frame2的sessionStorage,但是失败了,每次都会报安全异常。
既然如此,能否在调用webbrowser的代码中解决这个问题呢?早有人想到并解决了,跟COM交互并解决这个跨域问题
public class CrossFrameIE { // Returns null in case of failure. public static IHTMLDocument2 GetDocumentFromWindow(IHTMLWindow2 htmlWindow) { if (htmlWindow == null) { return null; } // First try the usual way to get the document. try { IHTMLDocument2 doc = htmlWindow.document; return doc; } catch (COMException comEx) { // I think COMException won't be ever fired but just to be sure ... if (comEx.ErrorCode != E_ACCESSDENIED) { return null; } } catch (System.UnauthorizedAccessException) { } catch { // Any other error. return null; } // At this point the error was E_ACCESSDENIED because the frame contains a document from another domain. // IE tries to prevent a cross frame scripting security issue. try { // Convert IHTMLWindow2 to IWebBrowser2 using IServiceProvider. IServiceProvider sp = (IServiceProvider)htmlWindow; // Use IServiceProvider.QueryService to get IWebBrowser2 object. Object brws = null; sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out brws); // Get the document from IWebBrowser2. SHDocVw.IWebBrowser2 browser = (SHDocVw.IWebBrowser2)(brws); return (IHTMLDocument2)browser.Document; } catch { } return null; } private const int E_ACCESSDENIED = unchecked((int)0x80070005L); private static Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046"); private static Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E"); } // This is the COM IServiceProvider interface, not System.IServiceProvider .Net interface! [ComImport(), ComVisible(true), Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] public interface IServiceProvider { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int QueryService(ref Guid guidService, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject); }到这里,问题基本有解了,但是如果继续使用invokeScript的方式,则在注入脚本的时候存在接口不匹配问题。CrossFrameIE拿到的接口是IHTMLDocument2,但是CreateElement需要的是HtmlDocument,这个差别最终导致没法建出需要的脚本,所以要想办法用另一个执行脚本的方法execScript并得到返回值,具体做法直接上代码
IHTMLWindow2 win = (IHTMLWindow2)this.webbrowser.Document.Window.Frames["frame1"].Frames["frame2"].DomWindow; CrossFrameIE.GetDocumentFromWindow(win).parentWindow.execScript("var returnValue; function test(){alert(window.sessionStorage['sensitiveData']);} test()", "javascript"); object obj = CrossFrameIE.GetDocumentFromWindow(win).Script.returnValue;
代码可以自行修正,但是最终obj就是我们想要的值
另一个问题是如何获取cookie,一般cookie获取其实比较容易
this.webbrowser.Document.Cookie但是经常需要获取带http_only的重要session,于是就比较复杂了,主要是调wininet.dll,据说最终是通过读取cookie文件来获取该cookie的,未考证过
private const int INTERNET_COOKIE_THIRD_PARTY = 0x00002000; //0x00002000 [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern bool InternetGetCookieEx(string pchURL, string pchCookieName, StringBuilder pchCookieData, ref System.UInt32 pcchCookieData, int dwFlags, IntPtr lpReserved); //使用下面代码片段,即可获得http_only cookie uint datasize = 2048; StringBuilder cookieData = new StringBuilder((int)datasize); if (InternetGetCookieEx((string) dict["url"], null, cookieData, ref datasize, INTERNET_COOKIE_THIRD_PARTY, IntPtr.Zero)) { session.updateCookie(cookieData.ToString()); }
webbrowser的几个帖子
http://www.cnblogs.com/txw1958/archive/2012/09/24/CSharp-WebBrowser.html http://blog.csdn.net/jintougao/article/details/12948633 http://www.cnblogs.com/peterzb/archive/2009/07/12/1521787.html
相关文章推荐
- C#下利用WebBrowser完整获取COOKIE
- C#利用WebBrowser获取完整COOKIE介绍
- 淘宝跨域获取Cookie分析
- C#基于WebBrowser获取cookie的实现方法
- 获取WebBrowser全cookie 和 httpWebRequest 异步获取页面数据
- 用script跳转方式主动跨域获取cookie或session
- 关于跨域获取cookie问题的解决
- 跨域获取cookie,多个网站实现一键…
- (转)用webbrowser做的网站登陆程序,如何获取cookie并且保存在程序中 (IE8有效) ,用途嘛,你懂的。
- webBrowser获取cookie
- 如何获取webbrowser的cookie
- C#利用WebBrowser获取完整COOKIE介绍
- Firefox Extention:nsICookieService 跨域获取Cookie
- 淘宝如何跨域获取Cookie分析
- c# 获取 webbrowser 完整 cookie
- C#下利用WebBrowser完整获取COOKIE
- 使用csExWB Webbrowser 控件获取HttpOnly的cookie
- paip.C#.NET利用WebBrowser获取完整COOKIE
- C#利用WebBrowser获取完整COOKIE
- webBrowser获取取Cookie不全的解决方法