为了登录网站的某个部分,我的应用程序的用户需要他们的cookie。要做到这一点,我需要抓住它并将其传递给url。
有谁知道如何从浏览器控件中获取某个网站cookie?
我看到this method但不太清楚。
谢谢,TP。
答案 0 :(得分:6)
从WP 7.1芒果“发布”开始,如果可以打电话,请参阅WebBrowser Control Overview for Windows Phone。它最近已经更新了一点,事实证明它们实际上已经从WebBrowser添加了对cookie检索的一些支持。在页面的底部,您会发现一个微小的链接GetCookies(WebBrowser)指向一个新类的描述:WebBrowserExtensions使用这个非常方便的方法。是的,这个班级只有一个成员。这是一种扩展方法,我想不需要解释。
我没有多玩过这种方法,但似乎这将允许你访问与JS技巧完全相同的东西:当前URL的cookie集。它可能不允许设置任何内容,也不允许查看其他URL的cookie。也许如果你努力玩CookieContainer,你会收到,但我怀疑。
在7.0版本中,我一直在努力为我的应用程序实现“cookie透明度”。长话短说,我的应用程序正在做一些后台HTTP请求,并且还有一个WebBrowser来显示一些在线内容 - 如果两个连接源都向服务器发出相同的cookie,那么“会很棒”。猜猜是什么,我的应用程序已发出第一个请求,然后让浏览器导航。有了这样的要求,实际上几乎没有办法实现cookies的一致性 - 即使使用当前新的和光荣的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用户身份验证,并且都没有做一些低级别的事情 - 因为所有这些设置都将与为当前“系统用户实例”存储的WebBrowser数据同步,如果我被允许在其上调用它单用户手机设备嘿。连接和WebBrowser之间的互操作双向 - 如果您的HTTP连接(使用'hidden property'创建)接收任何设置/ cookies /等 - 那么WebBrowser会立即注意到它们和更新自己的缓存。任何一方都没有cookie /会话损失!
如果您需要在第一次WebBrowser导航后为您的后续连接被动获取Cookie,请使用GetCookie或JS方式。 但是如果你需要你的代码是第一个,然后将authz传递给WebBrowser - 你可能需要深入挖掘并使用上面的内容..它已被隐藏,所以请先采用其他方法!
..并且不要问我是如何找到它或花了多少时间:P 用它玩得很开心
//编辑:我刚刚发现,BrowserHttp属性是访问浏览器连接工厂的正常Silverlight方式,请参阅BrowserHttp。它似乎只是隐藏在为WP7平台编写的'miniSilverlight'中!
答案 1 :(得分:0)
您链接的帖子中描述的方法是使用WebBrowser
控件的InvokeScript
方法运行一些javascript。但是这篇文章似乎使用了一个实际上并不存在的“cookies”集合。
string cookie = myWebBrowser.InvokeScript("document.cookie") as string;
现在,对于困难的部分,您获得的字符串包含页面的所有相关cookie名称/值对,其值仍为Url编码。您需要解析返回的字符串以获取所需的值。
请参阅document.cookie property文档。
修改强>:
看起来很新而不是依赖帖子,InvokeScript
在主机浏览器的窗口上调用命名函数。因此,WebBrowser中显示的页面本身需要包含如下函数: -
function getCookie() { return document.cookie; }
然后InvokeScript
看起来像: -
string cookie = myWebBrowser.InvokeScript("getCookie");
答案 2 :(得分:0)
// 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。然后,您可以解析字符串。
答案 3 :(得分:0)
正如@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<string, string> {
{"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时抛出的异常 - 它似乎抛出了“未找到”描述的WebException错误。
答案 4 :(得分:0)
有一个WebBrowser Extension类,它是为此精确开发的:
CookieCollection tempCookies = Microsoft.Phone.Controls.WebBrowserExtensions.GetCookies(this.BrowserControl);