在跟随 html link 时,如何防止 CefSharp 浏览器打开 2 windows?
How do I keep the CefSharp browser from opening 2 windows when following an html link?
我正在使用 CefSharp 浏览器来显示电子邮件的内容。我从已解析的电子邮件中提取 BodyHtmlText,并使用 browser.LoadHtml(BodyHtmlText, "http:\pixemail.com\");
将其加载到浏览器中。我希望 BodyHtmlText 中的 links 在系统默认浏览器中打开,所以我实现了 BrowserRequestHandler 并通过设置 browser.RequestHandler = BrowserRequestHandler;
告诉浏览器使用它
这很好用,除非 link 锚标记有 。当它出现时,点击 link 打开两个新的浏览器 windows;一个带有预期的 link 目标页面,另一个只是空的。 BrowserRequestHandler.OnBeforeBrowse()
仅调用一次,即使打开了 2 windows。
如何去掉空的window?
如果我不安装 BrowserRequestHandler,带有 target="_blank" 的 links 在没有额外 window 的新浏览器中打开,但是常规 links(没有target="_blank"),在应用程序的 CefSharp 浏览器 window 中打开,这是我不想要的。如果在 BrowserRequestHandler.OnBeforeBrowse()
中我可以检测到 link 有 target="_blank",我可以让 CefBrowser 处理它并获得我想要的行为。或者是否有其他方法来配置和使用 CefSharp 浏览器来获得我想要的行为?
CefSharp.MinimalExample.WinForms 的略微修改版本也存在同样的问题。我的 BrowserRequestHandler 看起来像这样:
public class BrowserRequestHandler : RequestHandler {
protected override bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame,
IRequest request, bool userGesture, bool isRedirect) {
// Open in external default browser (chrome)
if (!request.Url.StartsWith("file:") && !request.Url.StartsWith("devtools:")
&& !request.Url.StartsWith("chrome-devtools:") && !request.Url.Contains("pixemail.com")) {
Console.WriteLine($"start new browser at {request.Url}");
System.Diagnostics.Process.Start(request.Url);
return true;
}
return false; // let Cef handle the browse request
}
}
CefSharp.MinimalExample.WinForms.BrowserForm 的变化是:
string htmlPageFromEmail;
public BrowserForm() {
InitializeComponent();
htmlPageFromEmail = File.ReadAllText("test-email.html");
//...
browser = new ChromiumWebBrowser("http://pixemail.com/"); // a dummy web address
//...
BrowserRequestHandler = new BrowserRequestHandler();
browser.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;
//...
browser.Visible = true;
}
private void OnIsBrowserInitializedChanged(object sender, EventArgs e) {
var b = ((ChromiumWebBrowser) sender);
this.InvokeOnUiThreadIfRequired(() => {
b.LoadHtml(htmlPageFromEmail, "http://pixemail.com/");
b.Focus();
});
}
我用来模拟电子邮件 BodyHtmlText 字符串的测试-email.html 文件是:
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<br><br>Bad link. Opens 2 windows:
<a href="https://www.youtube.com/watch?v=_7Yw8qMDips&fbclid=IwAR1rGIK9KJukB4_KV5J-E3hqgfFPFZG8scobzKw_aw3jcUnrQWafr4Iw8bc" rel="nofollow" target="_blank" class="enhancr_card_3679327690">Jonny Quest Opening Titles in Stop Motion</a>
<br><br>Good link. Opens 1 window:
<a href="https://mewe.com/group/5e35fe0f260e8853cadbe7b7">https://mewe.com/group/5e35fe0f260e8853cadbe7b7</a>
<br><br>
</body>
</html>
我在 Windows 10 PC 和 Visual Studio 2019 上使用版本 CefSharp/84 和 x64 平台目标。
根据内存,OnBeforePopup 在 OnBeforeBrowse 之前调用,因此 CEF 在内部创建弹出窗口 window,然后您取消导航,导致空 window。在您的 OnBeforeBrowse 实现中,您应该发现 Browser.IsPopup 在 link 具有目标属性的情况下为真。
简而言之,您取消导航为时已晚,弹出窗口 window 已经创建。
两个选项是
- 实施 http://cefsharp.github.io/api/84.4.x/html/M_CefSharp_ILifeSpanHandler_OnBeforePopup.htm 并取消创建弹出窗口。
- 注入 JavaScript 以删除目标属性。
我正在使用 CefSharp 浏览器来显示电子邮件的内容。我从已解析的电子邮件中提取 BodyHtmlText,并使用 browser.LoadHtml(BodyHtmlText, "http:\pixemail.com\");
将其加载到浏览器中。我希望 BodyHtmlText 中的 links 在系统默认浏览器中打开,所以我实现了 BrowserRequestHandler 并通过设置 browser.RequestHandler = BrowserRequestHandler;
这很好用,除非 link 锚标记有 BrowserRequestHandler.OnBeforeBrowse()
仅调用一次,即使打开了 2 windows。
如何去掉空的window?
如果我不安装 BrowserRequestHandler,带有 target="_blank" 的 links 在没有额外 window 的新浏览器中打开,但是常规 links(没有target="_blank"),在应用程序的 CefSharp 浏览器 window 中打开,这是我不想要的。如果在 BrowserRequestHandler.OnBeforeBrowse()
中我可以检测到 link 有 target="_blank",我可以让 CefBrowser 处理它并获得我想要的行为。或者是否有其他方法来配置和使用 CefSharp 浏览器来获得我想要的行为?
CefSharp.MinimalExample.WinForms 的略微修改版本也存在同样的问题。我的 BrowserRequestHandler 看起来像这样:
public class BrowserRequestHandler : RequestHandler {
protected override bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame,
IRequest request, bool userGesture, bool isRedirect) {
// Open in external default browser (chrome)
if (!request.Url.StartsWith("file:") && !request.Url.StartsWith("devtools:")
&& !request.Url.StartsWith("chrome-devtools:") && !request.Url.Contains("pixemail.com")) {
Console.WriteLine($"start new browser at {request.Url}");
System.Diagnostics.Process.Start(request.Url);
return true;
}
return false; // let Cef handle the browse request
}
}
CefSharp.MinimalExample.WinForms.BrowserForm 的变化是:
string htmlPageFromEmail;
public BrowserForm() {
InitializeComponent();
htmlPageFromEmail = File.ReadAllText("test-email.html");
//...
browser = new ChromiumWebBrowser("http://pixemail.com/"); // a dummy web address
//...
BrowserRequestHandler = new BrowserRequestHandler();
browser.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;
//...
browser.Visible = true;
}
private void OnIsBrowserInitializedChanged(object sender, EventArgs e) {
var b = ((ChromiumWebBrowser) sender);
this.InvokeOnUiThreadIfRequired(() => {
b.LoadHtml(htmlPageFromEmail, "http://pixemail.com/");
b.Focus();
});
}
我用来模拟电子邮件 BodyHtmlText 字符串的测试-email.html 文件是:
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<br><br>Bad link. Opens 2 windows:
<a href="https://www.youtube.com/watch?v=_7Yw8qMDips&fbclid=IwAR1rGIK9KJukB4_KV5J-E3hqgfFPFZG8scobzKw_aw3jcUnrQWafr4Iw8bc" rel="nofollow" target="_blank" class="enhancr_card_3679327690">Jonny Quest Opening Titles in Stop Motion</a>
<br><br>Good link. Opens 1 window:
<a href="https://mewe.com/group/5e35fe0f260e8853cadbe7b7">https://mewe.com/group/5e35fe0f260e8853cadbe7b7</a>
<br><br>
</body>
</html>
我在 Windows 10 PC 和 Visual Studio 2019 上使用版本 CefSharp/84 和 x64 平台目标。
根据内存,OnBeforePopup 在 OnBeforeBrowse 之前调用,因此 CEF 在内部创建弹出窗口 window,然后您取消导航,导致空 window。在您的 OnBeforeBrowse 实现中,您应该发现 Browser.IsPopup 在 link 具有目标属性的情况下为真。
简而言之,您取消导航为时已晚,弹出窗口 window 已经创建。
两个选项是
- 实施 http://cefsharp.github.io/api/84.4.x/html/M_CefSharp_ILifeSpanHandler_OnBeforePopup.htm 并取消创建弹出窗口。
- 注入 JavaScript 以删除目标属性。