Захват файлов cookie в веб-браузере - WP7 - PullRequest
3 голосов
/ 18 ноября 2010

Для входа на определенную часть веб-сайта пользователям моего приложения требуется свой файл cookie. Для этого мне нужно взять его и передать URL.

Кто-нибудь знает, как получить cookie-файлы определенных веб-сайтов из элемента управления браузера?

Я видел этот метод , но не совсем ясно.

Спасибо, ТП.

Ответы [ 5 ]

6 голосов
/ 03 сентября 2011

Начиная с WP 7.1 Mango "release", если можно так назвать, см. Обзор управления веб-браузером для Windows Phone .Недавно он был немного обновлен, и оказалось, что они фактически добавили некоторую поддержку для поиска файлов cookie из WebBrowser.Внизу страницы вы найдете крошечную ссылку GetCookies (WebBrowser) , указывающую на описание нового класса: WebBrowserExtensions с помощью этого очень удобного метода.Да, у этого класса есть только один единственный член.Это метод расширения, я полагаю, что никаких объяснений по этому поводу не требуется.

Я не слишком много играл с этим методом, но, похоже, это позволит вам получить доступ к тому же самому трюку с JS: набор cookie длятекущий URL.Это, вероятно, не позволит ничего устанавливать или просматривать файлы cookie для других URL-адресов.Возможно, если вы будете усердно играть с CookieContainer, который вы получите, но я сомневаюсь.

В версии 7.0 я изо всех сил пытался добиться "прозрачности cookie" для моего приложения.Короче говоря, мое приложение выполняло несколько фоновых HTTP-запросов, а также имело веб-браузер для отображения некоторого онлайн-контента - и «было бы здорово», если бы оба источника соединений отправляли на сервер одинаковые файлы 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")

с этимсвойство, вы сможете получить «специальный» внутренний экземпляр IWebRequestCreate, который используется внутри WebBrowser.Открыв свои фоновые HTTP-запросы с этим классом, вы автоматически получите ваши куки-файлы, как если бы они были созданы / отправлены с помощью элемента управления WebBrowser, но, в свою очередь - вы НЕ сможете изменять http заголовки, пользователь обеспечивает аутентификацию пользователя http и ни один не делает несколько вещей низкого уровня - потому что все эти настройки будут синхронизированы с данными WebBrowser, сохраненными для текущего «экземпляра пользователя системы», если мне будет разрешено вызывать его как таковой на одномТелефонное устройство хех.Взаимодействие между соединениями и веб-браузером работает в обе стороны - если ваше HTTP-соединение (созданное с использованием «скрытого свойства») получает какие-либо настройки / файлы cookie / и т. Д. - тогда веб-браузер мгновенно заметит их и обновитсвой кеш.Без потери cookie / сеанса ни с одной из сторон!

Если вам необходимо пассивно получать куки для ваших последующих соединений после некоторой первой навигации в WebBrowser - пожалуйста, используйте GetCookie или JS.Но если вам нужно, чтобы ваш код был первым, а затем передал authz в WebBrowser - вам, вероятно, придется копать глубже и использовать вышеизложенное. Он скрыт, поэтому сначала прибегните к другим средствам!

.. и не спрашивайте меня, как я его нашел или сколько времени это заняло: P приятно провести время с этим

// edit: я только что узнал, что свойство BrowserHttpобычный способ Silverlight для доступа к фабрике соединений браузера, см. BrowserHttp .Кажется, что он был спрятан только в «miniSilverlight», написанном для платформы WP7!

0 голосов
/ 11 октября 2013

Существует класс расширения WebBrowser, специально разработанный для этого:

CookieCollection tempCookies = Microsoft.Phone.Controls.WebBrowserExtensions.GetCookies(this.BrowserControl);
0 голосов
/ 19 июня 2012

Как уже говорил @quetzalcoatl, вы можете использовать внутренний экземпляр WebRequestCreator для обмена файлами cookie между экземплярами браузера и экземплярами WebRequest. Вы не можете напрямую получить доступ к файлам cookie, я думаю, что это всего лишь мера безопасности со стороны Microsoft.

Этот код ниже создает объект WebReqeust, связанный с CookieContainer экземпляра WebBrowser. Затем он отправляет URL-адрес, чтобы войти в систему пользователя и сохранить куки в контейнере. После этого всем экземплярам браузера в экземпляре приложения будет необходим набор файлов 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 с описанием "Not found".

0 голосов
/ 21 января 2011
// 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 для документа. Затем вы можете разобрать строку.

0 голосов
/ 18 ноября 2010

Подход, описываемый в сообщении, которое вы связали, заключается в использовании InvokeScript метода WebBrowser control для запуска некоторого JavaScript. Однако, как представляется, пост использует коллекцию «куки», которой на самом деле не существует.

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

Теперь для сложной части полученная строка содержит все соответствующие пары имя / значение cookie для страницы со значениями, все еще закодированными по URL. Вам нужно будет проанализировать возвращенную строку на предмет нужного вам значения.

См. свойство document.cookie документация.

Редактировать

Глядя на это свежо, вместо того, чтобы полагаться на сообщение, InvokeScript вызывает именованную функцию в окне браузера хоста. Следовательно, страница, отображаемая в WebBrowser, сама должна включать такую ​​функцию: -

 function getCookie() { return document.cookie; }

Тогда InvokeScript будет выглядеть так: -

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