Установите файлы cookie для WebView2 в событии WebResourceRequested

Я использую новый элемент управления WebView2 (который находится в предварительной версии для разработчиков) для замены элемента управления WebBrowser в приложении Windows.Forms.

Основная причина перехода на элемент управления WebView2 заключается в том, что он основан на Chromium, который работает с WebRTC, тогда как элемент управления WebBrowser работает на Internet Explorer, который не поддерживает WebRTC.

Итак, проблема, с которой я столкнулся, - найти способ установить файл cookie для URL-адреса, по которому я хочу, чтобы WebView2 переходил. Раньше при использовании WebBrowser файлы cookie можно было установить, вызвав InternetSetCookie перед webBrowser.Navigate, но InternetSetCookie работает только с Internet Explorer.

Файл cookie должен быть установлен для аутентификации на стороннем веб-сайте, т. Е. Чтобы доказать веб-сайту, что мое приложение уже вошло в систему (это сделано несколькими моментами ранее другими частями моего приложения, которые не используют WebView2). Приложение успешно записывает файл cookie аутентификации в ответ на вход в систему, но я просто не могу найти, как передать файл cookie обратно на веб-сайт при навигации с помощью элемента управления WebView2. Элемент управления WebView2 используется для перехода на другую страницу того же веб-сайта, где используется WebRTC.

https://github.com/MicrosoftEdge/WebViewFeedback/issues/4 объясняет, что пока нет быстрого механизма для установки файлов cookie в WebView2, но предлагает обработать событие WebResourceRequested, а затем установить файл cookie, изменив запрос. Обработчик событий WebResourceRequested.

Так может ли кто-нибудь объяснить, как на самом деле запустить событие WebResourceRequested для WebView2, пожалуйста? Я безуспешно пробовал:

        private string myUrl = "https://www.somedomain.com";

        private void WebView_CoreWebView2Ready(object sender, EventArgs e)
        {
            webView.CoreWebView2.AddWebResourceRequestedFilter(myUrl,CoreWebView2WebResourceContext.All);
            webView.CoreWebView2.WebResourceRequested += CoreWebView2_WebResourceRequested;
        }

        private void CoreWebView2_WebResourceRequested(object sender, CoreWebView2WebResourceRequestedEventArgs e)
        {
            Uri myUri = new Uri(myUrl);

            if (myUri.IsBaseOf(e.Request.RequestUri))
            {
                e.Request.Headers.Add("Cookie", cookieName, authToken);
            }
        }

Событие WebResourceRequested никогда не срабатывает. Я попытался заставить его сработать, вызвав WebView2.Navigate, WebView2.CoreWebView2.Navigate и WebView2.Source, но ни один из них не вызывает срабатывания события WebResourceRequested.

Причина, по которой я подключаю обработчик событий для WebResourceRequested из события WebView_CoreWebView2Ready, заключается в том, что если вы попытаетесь подключить его раньше (например, при загрузке формы), CoreWebView2 будет иметь значение null, потому что для этого требуется больше времени. Я успешно подключил другие события внутри WebView_CoreWebView2Ready, и они сработали (например, событие NavigationStarting).

Спасибо.

2 ответа

Решение

Событие WebResource Requested запускается только тогда, когда существует активный фильтр для ресурса и этот фильтр соответствует. Вы можете добавить фильтр, который перехватывает все запросы, используя

WebView2.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);

Чтобы сузить и обновить фильтр актуальных запросов, которые вас интересуют, вы можете проверить args.Request.RequestUri внутри события CoreWebView2OnWebResourceRequested.

Создав локальный сервер и подключившись к нему через WebView, вы можете видеть, что предварительный просмотр WebView не копирует файлы cookie при преобразовании.NET HttpRequest в COM WebRequest, который используется самим WebView.

using (HttpListener listener = new HttpListener())
{
    listener.Prefixes.Add($"http://localhost:8080/");
    listener.Start();

    while (listener.IsListening)
    {
        var context = await listener.GetContextAsync();

        using (var response = context.Response)
        {
            for (int i = 0; i < context.Request.Headers.Count; i++)
            {
                Console.WriteLine($"{context.Request.Headers.GetKey(i)} : {context.Request.Headers.Get(i)}");
            }
            
            using (var writer = new StreamWriter(response.OutputStream))
            {
                context.Response.ContentType = "text";
                writer.WriteLine("Test.");
                writer.Flush();
            }
        }
    }
}

Вероятно, вам следует отправить отчет об ошибке для предварительного просмотра Edge WebView.

Я обнаружил, что причина, по которой я не могу установить файлы cookie изнутри в обработчике событий WebResourceRequested, заключается в том, что это известная ошибка, о которой уже было сообщено в Microsoft здесь:

Невозможно установить заголовки в обработчике событий WebResourceRequested.

Итак, в заключение мой код действительно показывает, как правильно добавить файлы cookie, но он не будет работать, пока ошибка не будет исправлена ​​Microsoft.

Я понимаю, что этот ответ не предлагает обходного пути, но он, по крайней мере, отвечает на вопрос, почему в настоящее время код не может добавить файл cookie.

Другие вопросы по тегам