说明:在同一窗口打开链接,只要稍加改造就可以实现,这里实现的是在新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; System; System.Collections.Generic; System.linq; System.Text; System.Threading.Tasks; System.Security.Cryptography.X509Certificates;namespace CefSharpDemo{ public class RequestHandler : IRequestHandler { private ExtChromiumbrowser _browser; public RequestHandler(ExtChromiumbrowser browser) { _browser = browser; } bool GetAuthCredentials(IWebbrowser chromiumWebbrowser,Ibrowser browser,string originUrl,1)">bool isProxy,1)">string host,1)">int port,1)">string realm,1)">string scheme,IAuthCallback callback) { return false; } public IResourceRequestHandler GetResourceRequestHandler(IWebbrowser chromiumWebbrowser,iframe frame,IRequest request,1)">bool isNavigation,1)">bool isDownload,1)">string requestinitiator,1)">ref bool DisabledefaultHandling) { if (request.Method.toupper() == "POST" && request.PostData != null) { if (request.PostData.Elements.Count > 0) { _browser.PostData = new byte[request.PostData.Elements[].Bytes.Length]; request.PostData.Elements[0].Bytes.copyTo(_browser.PostData,); } } bool OnBeforebrowse(IWebbrowser chromiumWebbrowser,1)">bool userGesture,1)"> isRedirect) { bool OnCertificateError(IWebbrowser chromiumWebbrowser,CefErrorCode errorCode,1)"> requestUrl,ISslinfo sslinfo,IRequestCallback callback) { bool OnopenUrlFromTab(IWebbrowser chromiumWebbrowser,1)">string targetUrl,WindowOpendisposition targetdisposition,1)"> userGesture) { voID OnPluginCrashed(IWebbrowser chromiumWebbrowser,1)"> pluginPath) { } bool OnQuotaRequest(IWebbrowser chromiumWebbrowser,1)">long newSize,1)">voID OnRenderProcessterminated(IWebbrowser chromiumWebbrowser,CefTerminationStatus status) { } OnRenderVIEwReady(IWebbrowser chromiumWebbrowser,Ibrowser browser) { } bool OnSelectClIEntCertificate(IWebbrowser chromiumWebbrowser,1)">int port,X509Certificate2Collection certificates,ISelectClIEntCertificateCallback callback) { ; } }}VIEw Code
二、实现IlifeSpanHandler接口
System.Collections.Specialized; System.Runtime.InteropServices; System.Threading; System.windows; System.windows.Interop; Utils; CeflifeSpanHandler : CefSharp.IlifeSpanHandler { private static limitedTaskScheduler _scheduler = new limitedTaskScheduler(2); CeflifeSpanHandler() { } DoClose(IWebbrowser browserControl,CefSharp.Ibrowser browser) { if (browser.Isdisposed || browser.IsPopup) { ; } true OnAfterCreated(IWebbrowser browserControl,1)"> OnBeforeClose(IWebbrowser browserControl,Ibrowser browser) { } bool OnBeforePopup(IWebbrowser browserControl,1)">string targetFramename,IPopupFeatures popupFeatures,IWindowInfo windowInfo,IbrowserSettings browserSettings,1)">bool noJavaScriptAccess,1)">out IWebbrowser newbrowser) { var chromiumWebbrowser = (ExtChromiumbrowser)browserControl; chromiumWebbrowser.dispatcher.Invoke(new Action(() => { browserPopupWin win = new browserPopupWin(); win.ShowInTaskbar = ; win.Height = ; win.WIDth = ; win.Show(); IntPtr handle = WindowInteropHelper(win).Handle; windowInfo.SetAsChild(handle); _scheduler.Run(() => { WaitUtil.Wait(() => chromiumWebbrowser.PostData); IRequest request = ; if (chromiumWebbrowser.PostData != ) { request = frame.CreateRequest(); request.Url = targetUrl; request.Method = "; request.InitializePostData(); var element = request.PostData.CreatePostDataElement(); element.Bytes = chromiumWebbrowser.PostData; request.PostData.AddElement(element); chromiumWebbrowser.PostData = ; } chromiumWebbrowser.dispatcher.Invoke( { NewWindowEventArgs e = NewWindowEventArgs(targetUrl,request); chromiumWebbrowser.OnNewWindow(e); })); chromiumWebbrowser.dispatcher.Invoke( { win.Close(); })); }); })); newbrowser = ; ; } }}VIEw Code
三、扩展ChromiumWebbrowser
CefSharp.Wpf; System.Threading.Tasks; ExtChromiumbrowser : ChromiumWebbrowser { byte[] PostData { get; set; } ExtChromiumbrowser() : base() { this.lifeSpanHandler = CeflifeSpanHandler(); this.DownloadHandler = new DownloadHandler(this); this.MenuHandler = MenuHandler(); this.KeyboardHandler = KeyboardHandler(); this.RequestHandler = new RequestHandler(); } event EventHandler<NewWindowEventArgs> StartNewWindow; OnNewWindow(NewWindowEventArgs e) { if (StartNewWindow != ) { StartNewWindow(,e); } } ClearHandlers() { //如果不清理Handler,会导致子进程CefSharp.browserSubprocess.exe无法释放 ; } }}VIEw Code
四、封装ExtChromiumbrowser(browserCtrl控件)
System.ComponentModel; System.IO; System.windows.Controls; System.windows.Data; System.windows.documents; System.windows.input; System.windows.Media; System.windows.Media.Imaging; System.windows.Navigation; System.windows.Shapes; CefSharpDemo{ /// <summary> /// 浏览器用户控件 </summary> partial browserCtrl : UserControl,Idisposable { #region 外部方法 /* [Dllimport("user32.dll",SetLastError = true)] private static extern IntPtr SetParent(IntPtr hWndChild,IntPtr hWndNewParent); [Dllimport("user32.dll",SetLastError = true)] public static extern IntPtr findwindowex(IntPtr parentHandle,IntPtr childAfter,string classname,string windowTitle); [Dllimport("user32.dll",SetLastError = true)] public static extern int MoveWindow(IntPtr hWnd,int x,int y,int nWIDth,int nHeight,bool BRePaint); [Dllimport("user32.dll",SetLastError = true)] public static extern int CloseWindow(IntPtr hWnd); [Dllimport("User32.dll",EntryPoint = "GetwindowText")] private static extern int GetwindowText(IntPtr hwnd,StringBuilder lpString,int nMaxCount); */ #endregion #region 变量属性事件 static bool _isCefInited = ; object _lockObject = object(); JsObject _JsObject; bool _firstLoad = ; <summary> 在此事件中设置URL(此事件已在线程中执行,此事件已对错误情况进行处理) </summary> event EventHandler SetUrlEvent; URL string Url { public IRequest Request { ; } 浏览器FrameLoadEnd事件 EventHandler FrameLoadEnd; ExtChromiumbrowser browser { get { WaitUtil.Wait(() => this._browser != null && this._browser.IsInitialized && _isCefInited); ._browser; } } ); #region 构造函数 browserCtrl() { InitializeComponent(); if (DesignerPropertIEs.GetIsInDesignmode(this)) return; this.Loaded += browserCtrl_Loaded; lock (_lockObject) { if (!_isCefInited) { _isCefInited = ; InitCef();初始化CefSharp } } _browser = ExtChromiumbrowser(); Bindbrowser(_browser); grID.Children.Add(_browser); } #region browserCtrl_Loaded voID browserCtrl_Loaded( sender,RoutedEventArgs e) { } #region SetMapCtrl 设置Map控件接口,用于C#和Js互 *** 作 SetMapCtrl(IMapCtrl mapCtrl) { _JsObject.MapCtrl = mapCtrl; } #region dispose 释放资源 释放资源 dispose() { 如果有d出窗口则先释放它 foreach (UIElement item in grID.Children) { if (item is browserContainer) { (item as browserContainer).ClearResource(); } } _browser.ClearHandlers(); if (_browser != null && !_browser.Isdisposed) { _browser.dispose(); } } #region Load voID Load( url) { .IsNullOrWhiteSpace(url)) { loadingWait.Visibility = Visibility.Visible; Url = url; _scheduler.Run(() => { #region Wait WaitUtil.Wait(() => { if (this._browser == null) ; this._browser.IsInitialized) if (!_isCefInited) bool isbrowserInitialized = this.dispatcher.Invoke(() => { isbrowserInitialized = ._browser.IsbrowserInitialized; }); if (!isbrowserInitialized) ; }); #endregion _browser.Load(Url); }); } } #region LoadUrl LoadUrl() { if (_firstLoad) { _firstLoad = ; _scheduler.Run(() =>#endregion if (Url == null && SetUrlEvent != ) { try { SetUrlEvent(this,1)">); } catch (Exception ex) { LogUtil.Error(ex,browserCtrl LoadUrl error 获取URL失败); } } elsethis.dispatcher.Invoke( { loadingWait.Visibility = Visibility.Collapsed; })); } if (Url != { if (Request == ) { _browser.Load(Url); } { _browser.Load(Url); _browser.GetMainFrame().LoadRequest(Request); Request = ; } } browserCtrl LoadUrl error Load URL失败 Visibility.Collapsed; })); } }); } } #region Bindbrowser Bindbrowser(ExtChromiumbrowser browser) { _JsObject = JsObject(); browser.RegisterJsObject(JsObj",_JsObject,1)">new CefSharp.BindingOptions { CamelCaseJavaScriptnames = }); browser.IsbrowserInitializedChanged += (ss,ee) => { LoadUrl(); }; browser.FrameLoadStart += (ss,1)"> { this.dispatcher.BeginInvoke( { (ss as ExtChromiumbrowser).Focus(); })); }; browser.FrameLoadEnd += (ss,1)"> { loadingWait.Visibility = Visibility.Collapsed; })); if (FrameLoadEnd != ) { FrameLoadEnd(null,1)">); } }; browser.KeyDown += (ss,1)">if (ee.Key == Key.F5) { { browser.Reload(); } (Exception ex) { LogUtil.Error(ex,1)">ExtChromiumbrowser Reload error); } } }; browser.PrevIEwTextinput += (o,e) =>foreach (var character in e.Text) { 把每个字符向浏览器组件发送一遍 browser.Getbrowser().GetHost().SendKeyEvent((int)WM.CHAR,(int)character,1)">); } 不让cef自己处理 e.Handled = ; }; browser.LoadError += (s,1)"> Visibility.Collapsed; })); }; } #region RegisterJsObject voID RegisterJsObject(string name,1)">object objectToBind,BindingOptions options = ) { ) { _browser.RegisterJsObject(name,objectToBind,options); } } (Exception ex) { LogUtil.Error(ex,1)">browserCtrl RegisterJsObject 错误); } } #region 初始化CefSharp InitCef() { string cefsharpFolder = CefSharpvar settings = CefSettings(); The location where cache data will be stored on disk. If empty an in-memory cache will be used for some features and a temporary disk cache for others. HTML5 databases such as localstorage will only persist across sessions if a cache path is specifIEd. settings.CachePath = cefsharpFolder + /cache"; 设置cache目录 settings.MultiThreadedMessageLoop = ; CefSharpSettings.FocusednodeChangedEnabled = ; CefSharpSettings.LegacyJavaScriptBindingEnabled = ; CefSharpSettings.ShutdownOnExit = ; CefSharpSettings.SubprocessExitIfParentProcessClosed = string logDir = AppDomain.CurrentDomain.BaseDirectory + cefsharpFolder + /log/Directory.Exists(logDir)) { Directory.CreateDirectory(logDir); } settings.browserSubprocesspath = AppDomain.CurrentDomain.BaseDirectory + cefsharpFolder + /CefSharp.browserSubprocess.exe; settings.Logfile = logDir + DateTime.Now.ToString(yyyyMMdd") + .log; settings.LocalesDirPath = AppDomain.CurrentDomain.BaseDirectory + cefsharpFolder + /locales; settings.CefCommandlineArgs.Add(disable-gpu1); settings.CefCommandlineArgs.Add(enable-media-stream); if (!Cef.Initialize(settings,performDependencyCheck: true,browserProcessHandler: browserProcessHandler())) { throw new Exception(Unable to Initialize Cef }}VIEw Code
五、MainWindow测试代码
CefSharp Demo 窗体 MainWindow : Window { MainWindow() { InitializeComponent(); tabControl.AddTabItemEvent += tabControl_AddTabItemEvent; Application.Current.MainWindow = voID tabControl_AddTabItemEvent(CreateTabItem("https://www.cnblogs.com/"); CreateTabItem(file:///D:/_程序/CefSharpDemo/post.HTML); } 新增Tab页 voID CreateTabItem(string url = ) { TabItem tabItem = TabItem(); tabItem.header = 新标签页; browserDemoCtrl ctrl = browserDemoCtrl(); ctrl.browserCtrl.browser.StartNewWindow += (s,1)"> { CreateTabItem(e.TargetUrl,e.Request); }; ctrl.browserCtrl.SetUrlEvent += (s,1)"> { ctrl.browserCtrl.Url = url; ctrl.browserCtrl.Request = request; }; tabItem.Content = ctrl; tabControl.Items.Add(tabItem); tabControl.SelectedItem = tabItem; ScrollVIEwer scrollVIEwer = tabControl.Template.Findname(scrollVIEwer ScrollVIEwer; scrollVIEwer.ScrollToRightEnd(); } voID Window_Closed(关闭窗体清理资源 程序退出时删除cache CefSharp.Cef.Shutdown(); string cachePath = AppDomain.CurrentDomain.BaseDirectory + CefSharp\cache (Directory.Exists(cachePath)) { string path Directory.GetDirectorIEs(cachePath)) { Directory.Delete(path,); } string file Directory.Getfiles(cachePath)) { if (!file.Tolower().Contains(cookies)) { file.Delete(file); } } } } }}VIEw Code
六、测试HTML代码post.HTML
<!DOCTYPE HTML><HTMLhead> Title>CefSharpDemo</> Meta charset="utf-8" /> http-equiv="X-UA-Compatible" content="IE=edge"name="vIEwport"="wIDth=device-wIDth,initial-scale=1"style type="text/CSS"stylescript ="text/JavaScript"scriptbody<!--enctype="multipart/form-data"--> form method="post" action="http://localhost:1209/netCMS/" target="_blank"> span>name:><input ="text" name="name" value="测试名称" /> >code:="code"="测试编码" /> button ="submit">Post提交buttonform>VIEw Code
七、测试后台代码
ActionResult index(){ string name = Request.Params[name]; string code = Request.Params[code]; VIEwBag.name = name; VIEwBag.code = code; VIEw();}VIEw Code
八、测试前台csHTML代码
@using Models;@{ Layout = "~/VIEws/Shared/_SiteLayout.csHTML";}div ="Font-size:50px; height:1200px;">@VIEwBag.namebr /><>@VIEwBag.codediv>VIEw Code
九:关键代码段:
1、RequestHandler类中获取并保存PostData
DisabledefaultHandling){ ) { ) { _browser.PostData = ].Bytes.Length]; request.PostData.Elements[); } } ;}VIEw Code
2、CeflifeSpanHandler类中创建IRequest
IWebbrowser newbrowser){ (ExtChromiumbrowser)browserControl; chromiumWebbrowser.dispatcher.Invoke( { browserPopupWin win = browserPopupWin(); win.ShowInTaskbar = ; win.Height = ; win.WIDth = ; win.Show(); IntPtr handle = WindowInteropHelper(win).Handle; windowInfo.SetAsChild(handle); _scheduler.Run(() => { WaitUtil.Wait(() => chromiumWebbrowser.PostData); IRequest request = ) { request = frame.CreateRequest(); request.Url = targetUrl; request.Method = ; request.InitializePostData(); request.PostData.CreatePostDataElement(); element.Bytes = chromiumWebbrowser.PostData; request.PostData.AddElement(element); chromiumWebbrowser.PostData = ; } chromiumWebbrowser.dispatcher.Invoke( { NewWindowEventArgs e = { win.Close(); })); }); })); newbrowser = ; ;}VIEw Code
说明:OnBeforePopup方法要return false,用browserPopupWin和windowInfo.SetAsChild方法d出一个不可见的窗体,这样才能拿到PostData
3、在browserCtrl控件中用LoadRequest方法打开新的URL,并把post数据带过去
){ _browser.Load(Url);}{ _browser.Load(Url); _browser.GetMainFrame().LoadRequest(Request); Request = ;}VIEw Code
十、效果图:
完整代码下载:https://files-cdn.cnblogs.com/files/s0611163/CefSharpDemo.zip
源码说明:为了减少源码压缩包的大小,代码中没有依赖的CefSharp文件,请自己下载(使用x86版本),用于测试的网页后台代码也没有,请自己制作测试后台
总结
以上是内存溢出为你收集整理的CefSharp禁止d出新窗体,在同一窗口打开链接,或者在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接全部内容,希望文章能够帮你解决CefSharp禁止d出新窗体,在同一窗口打开链接,或者在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)