CefSharp禁止弹出新窗体,在同一窗口打开链接,或者在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接
说明:在同一窗口打开链接,只要稍加改造就可以实现,这里实现的是在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接
github和bitbucket上相关问题:
1、WPF empty POST data when using custom popup https://github.com/cefsharp/CefSharp/issues/1267
2、CefLifeSpanHandler, customized OnBeforePopup problem https://bitbucket.org/chromiumembedded/cef/issues/1949/
解决(CefSharp版本75.1.143.0):
一、实现IRequestHandler接口
using CefSharp; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Security.Cryptography.X509Certificates; namespace CefSharpDemo { public class RequestHandler : IRequestHandler { private ExtChromiumBrowser _browser; public RequestHandler(ExtChromiumBrowser browser) { _browser = browser; } public bool GetAuthCredentials(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback) { return false; } public IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling) { if (request.Method.ToUpper() == "POST" && request.PostData != null) { if (request.PostData.Elements.Count > 0) { _browser.PostData = new byte[request.PostData.Elements[0].Bytes.Length]; request.PostData.Elements[0].Bytes.CopyTo(_browser.PostData, 0); } } return null; } public bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect) { return false; } public bool OnCertificateError(IWebBrowser chromiumWebBrowser, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback) { return false; } public bool OnOpenUrlFromTab(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) { return false; } public void OnPluginCrashed(IWebBrowser chromiumWebBrowser, IBrowser browser, string pluginPath) { } public bool OnQuotaRequest(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, long newSize, IRequestCallback callback) { return false; } public void OnRenderProcessTerminated(IWebBrowser chromiumWebBrowser, IBrowser browser, CefTerminationStatus status) { } public void OnRenderViewReady(IWebBrowser chromiumWebBrowser, IBrowser browser) { } public bool OnSelectClientCertificate(IWebBrowser chromiumWebBrowser, IBrowser browser, bool isProxy, string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback) { return false; } } }
二、实现ILifeSpanHandler接口
using CefSharp; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Interop; using Utils; namespace CefSharpDemo { public class CefLifeSpanHandler : CefSharp.ILifeSpanHandler { private static LimitedTaskScheduler _scheduler = new LimitedTaskScheduler(2); public CefLifeSpanHandler() { } public bool DoClose(IWebBrowser browserControl, CefSharp.IBrowser browser) { if (browser.IsDisposed || browser.IsPopup) { return false; } return true; } public void OnAfterCreated(IWebBrowser browserControl, IBrowser browser) { } public void OnBeforeClose(IWebBrowser browserControl, IBrowser browser) { } public bool OnBeforePopup(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser) { var chromiumWebBrowser = (ExtChromiumBrowser)browserControl; chromiumWebBrowser.Dispatcher.Invoke(new Action(() => { BrowserPopupWin win = new BrowserPopupWin(); win.ShowInTaskbar = false; win.Height = 0; win.Width = 0; win.Show(); IntPtr handle = new WindowInteropHelper(win).Handle; windowInfo.SetAsChild(handle); _scheduler.Run(() => { WaitUtil.Wait(() => chromiumWebBrowser.PostData); IRequest request = null; if (chromiumWebBrowser.PostData != null) { request = frame.CreateRequest(); request.Url = targetUrl; request.Method = "POST"; request.InitializePostData(); var element = request.PostData.CreatePostDataElement(); element.Bytes = chromiumWebBrowser.PostData; request.PostData.AddElement(element); chromiumWebBrowser.PostData = null; } chromiumWebBrowser.Dispatcher.Invoke(new Action(() => { NewWindowEventArgs e = new NewWindowEventArgs(targetUrl, request); chromiumWebBrowser.OnNewWindow(e); })); chromiumWebBrowser.Dispatcher.Invoke(new Action(() => { win.Close(); })); }); })); newBrowser = null; return false; } } }