在 WebResourceRequested 事件中为 WebView2 设置 cookie
Posted
技术标签:
【中文标题】在 WebResourceRequested 事件中为 WebView2 设置 cookie【英文标题】:Set cookies for WebView2, in WebResourceRequested event 【发布时间】:2020-10-06 12:48:47 【问题描述】:我正在使用新的 WebView2 控件(在开发人员预览版中)替换 Windows.Forms 应用程序中的 WebBrowser 控件。
切换到 WebView2 控件的主要原因是它基于与 WebRTC 兼容的 Chromium,而 WebBrowser 控件由不支持 WebRTC 的 Internet Explorer 提供支持。
所以我遇到的问题是找到一种方法来为我希望 WebView2 导航到的 url 设置一个 cookie。过去在使用WebBrowser时,可以通过在webBrowser.Navigate之前调用InternetSetCookie来设置cookies,但是InternetSetCookie只适用于Internet Explorer。
需要在第三方网站上为身份验证设置 cookie,即向网站证明我的应用程序已经登录(由我的应用程序的其他未使用 WebView2 的部分早些时候完成)。该应用程序成功捕获了登录响应中的身份验证 cookie,但在使用 WebView2 控件导航时,我只是找不到如何将 cookie 传递回网站。 WebView2 控件用于导航到同一网站上使用 WebRTC 的另一个页面。
https://github.com/MicrosoftEdge/WebViewFeedback/issues/4 解释说目前还没有提供用于在 WebView2 中设置 cookie 的快速机制,但建议处理 WebResourceRequested 事件,然后通过修改 WebResourceRequested 事件处理程序内部的 request.Header 来设置 cookie。
那么谁能解释一下如何真正让 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 事件。
我从 WebView_CoreWebView2Ready 事件中为 WebResourceRequested 连接事件处理程序的原因是,如果您尝试更早地连接它(例如在表单加载中),那么 CoreWebView2 将为空,因为它需要更多时间。我已经成功连接了 WebView_CoreWebView2Ready 中的其他事件并且它们确实触发了(例如 NavigationStarting 事件)。
谢谢。
【问题讨论】:
【参考方案1】:WebResource Requested 事件仅在资源的活动过滤器存在并且该过滤器匹配时才会触发。您可以使用添加一个过滤器来拦截所有请求
WebView2.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
要缩小和更新您感兴趣的实际请求的过滤器,您可以检查 CoreWebView2OnWebResourceRequested 事件中的args.Request.RequestUri
。
通过创建本地服务器并通过 WebView 连接到它,您可以看到在将 .NET HttpRequest 转换为 WebView 本身使用的 COM WebRequest 时,WebView 预览不会复制 cookie。
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 预览提交错误报告。
【讨论】:
所以只需要了解为什么忽略此行:e.Request.Headers.Add("Cookie", cookieName, authToken); 我已经编辑了问题以展示如何检查 args.Request.RequestUri,谢谢@ZiggZagg。【参考方案2】:我发现我无法在 WebResourceRequested 事件处理程序中设置 cookie 的原因是因为这是一个已在此处报告给 Microsoft 的已知错误:
Unable to set headers in WebResourceRequested event handler
因此,总而言之,我的代码确实显示了添加 cookie 的正确方法,但在 Microsoft 修复错误之前它不会起作用。
我很欣赏这个答案没有提供解决方法,但它至少回答了为什么代码当前无法添加 cookie 的问题。
【讨论】:
以上是关于在 WebResourceRequested 事件中为 WebView2 设置 cookie的主要内容,如果未能解决你的问题,请参考以下文章