CefSharp禁止d出新窗体,在同一窗口打开链接,或者在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接

CefSharp禁止d出新窗体,在同一窗口打开链接,或者在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接,第1张

概述说明:在同一窗口打开链接,只要稍加改造就可以实现,这里实现的是在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接 gi

 说明:在同一窗口打开链接,只要稍加改造就可以实现,这里实现的是在新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"的链接所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1212633.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存