Установите файлы 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.