在Web浏览器控件中抓取Cookie – WP7

为了登录网站的某个部分,我的应用程序的用户需要他们的cookie。 要做到这一点,我需要抓住它并将其传递给url。

有谁知道如何从浏览器控件中获取某些网站cookie?

我看到了这种方法但不太清楚。

谢谢,TP。

从WP 7.1 Mango“发布”开始,如果可以调用它,请参阅Windows Phone的WebBrowser控件概述 。 它最近更新了一点,事实certificate它们实际上已经从WebBrowser添加了对cookie检索的一些支持。 在页面的底部,你会发现一个微小的链接GetCookies(WebBrowser)指向一个新类的描述: WebBrowserExtensions使用这个非常方便的方法。 是的,这个class只有一个单一的成员。 这是一种扩展方法,我想不需要解释。

我没有多玩过这种方法,但似乎这将允许你访问与JS技巧完全相同的东西:当前URL的cookie集。 它可能不允许设置任何内容,也不允许查看其他URL的cookie。 也许如果你努力玩CookieContainer,你会收到,但我怀疑。

在7.0版本中,我一直在努力为我的应用程序实现“cookie透明度”。 长话短说,我的应用程序正在做一些后台HTTP请求,并且还有一个WebBrowser来显示一些在线内容 – 如果两个连接源都向服务器发出相同的cookie,那就“很棒”。猜猜是什么,我的应用程序必须发出第一个请求,然后让浏览器导航。 有了这样的要求,实际上几乎没有办法实现cookie的一致性 – 即使使用当前新的和光荣的GetCookie方法,我想这将是非常难的。 所以,重点 – 它是可能的,但需要使用一些隐藏的API,它在电话上公开存在,但隐藏在SDK中。 API可用于(公共)类System.Net.Browser.WebRequestCreator ,可免费使用。 怪癖是:在SDK中,这个类有一个公共静态属性“IWebRequestCreate ClientHttp”,其中有一个方法“Create”,可用于“生产”你的“原始http”连接 – 如果你不想使用WebClient某些原因。 在手机和模拟器上,有一个名为“IWebRequestCreate BrowserHttp”第二个公共静态属性 ,很容易被Reflection返回:

PropertyInfo brwhttp = typeof(System.Net.Browser.WebRequestCreator) .GetProperty("BrowserHttp") 

使用此属性,您将能够获得WebBrowser内部使用的IWebRequestCreate的“特殊”内部实例。 通过使用此类打开后台HTTP请求,您将自动设置cookie,就好像它们是由WebBrowser控件创建/发送的一样,但反过来 – 您将无法修改 http标头,用户提供http用户身份validation,也不会一些低级别的东西 – 因为所有这些设置都将与为当前“系统用户实例”存储的WebBrowser数据同步,如果我被允许在单用户电话设备上调用它就好了。 连接和WebBrowser之间的互操作两种方式 – 如果您的HTTP连接(使用’隐藏属性’创建)接收任何设置/ cookie /等 – 那么WebBrowser将立即注意到它们并更新自己的缓存。 双方都没有cookie /会话丢失!

如果您需要在第一次WebBrowser导航后被动地为后续连接获取cookie – 请使用GetCookie或JS方式。 但是如果你需要你的代码是第一个,然后将authz传递给WebBrowser – 你可能需要深入挖掘并使用上面的…它已被隐藏,所以请先采取其他方法!

..并且不要问我是如何找到它或花了多少时间:P有一个很好玩的

//编辑:我刚刚发现,BrowserHttp属性是正常的Silverlight访问浏览器连接工厂的方式,请参阅BrowserHttp 。 它似乎只是隐藏在为WP7平台编写的’miniSilverlight’中!

您链接的post中描述的方法是使用WebBrowser控件的InvokeScript方法来运行一些javascript。 但是这篇文章似乎使用了一个实际上并不存在的“cookies”集合。

  string cookie = myWebBrowser.InvokeScript("document.cookie") as string; 

现在,对于困难的部分,您获得的字符串包含页面的所有相关cookie名称/值对,其值仍为Url编码。 您需要解析返回的字符串以获取所需的值。

请参阅document.cookie属性文档。

编辑

看起来很新鲜而不依赖于post, InvokeScript在主机浏览器的窗口上调用命名函数。 因此,在WebBrowser中显示的页面本身需要包含如下函数: –

  function getCookie() { return document.cookie; } 

然后InvokeScript看起来像: –

  string cookie = myWebBrowser.InvokeScript("getCookie"); 

正如@quetzalcoatl已经建议的那样,您可以使用WebRequestCreator的内部实例在浏览器实例和WebRequest实例之间共享cookie。 你不能直接访问cookie,我认为这只是微软的一项安全措施。

下面的代码创建了一个WebReqeust对象,该对象连接到WebBrowser实例的CookieContainer。 然后它发布到URL以登录用户并将cookie存储在容器中。 完成后,应用程序实例中的所有浏览器实例都将具有所需的cookie集。

 var browser = new WebBrowser(); var brwhttp = typeof (WebRequestCreator).GetProperty("BrowserHttp"); var requestFactory = brwhttp.GetValue(browser, null) as IWebRequestCreate; var uri = new Uri("https://www.login.com/login-handler"); var req = requestFactory.Create(uri); req.Method = "POST"; var postParams = new Dictionary { {"username", "turtlepower"}, {"password": "ZoMgPaSSw0Rd1"} }; req.BeginGetRequestStream(aReq => { var webRequest = (HttpWebRequest)aReq.AsyncState; using (var postStream = webRequest.EndGetRequestStream(aReq)) { // Build your POST request here var postDataBuilder = new StringBuilder(); foreach (var pair in paramsDict) { if (postDataBuilder.Length != 0) { postDataBuilder.Append("&"); } postDataBuilder.AppendFormat("{0}={1}", pair.Key, HttpUtility.UrlEncode(pair.Value)); } var bytes = Encoding.UTF8.GetBytes(postDataBuilder.ToString()); postStream.Write(bytes, 0, bytes.Length); } // Receive response webRequest.BeginGetResponse(aResp => { var webRequest2 = (HttpWebRequest) aResp.AsyncState; webRequest = (HttpWebRequest)aResp.AsyncState; string resp; using (var response = (HttpWebResponse)webRequest2.EndGetResponse(aResp)) { using (var streamResponse = response.GetResponseStream()) { using (var streamReader = new System.IO.StreamReader(streamResponse)) { resp = streamReader.ReadToEnd(); } } } }, webRequest); }, req); 

我无法解决的问题之一是当服务器返回302时抛出的exception – 它似乎抛出WebException错误并带有“Not found”描述。

 // Ensure this is set to true BEFORE navigating to the page webBrowser1.IsScriptEnabled = true; // Once the page has loaded, you can read the cookie string string cookieString = webBrowser1.InvokeScript("eval", new string[] { "document.cookie;" }) as string; 

cookieString变量将包含文档的完整cookie。 然后,您可以解析字符串。

有一个WebBrowser扩展类,它是为此精确开发的:

 CookieCollection tempCookies = Microsoft.Phone.Controls.WebBrowserExtensions.GetCookies(this.BrowserControl);