CefSharp 获取POST(AJAX)、GET消息返回值(request)

    CefSharp作为专门为爬虫工具开发的库比Selenium这种开发目的是页面测试工具然后用来做爬虫的工具要贴心得多。我们操作网页的时候发送或者做了某个动作提交表单之后需要知道我们的动作或者提交是否成功,因为有的页面会因为网络延迟问题提交失败,需要准确的获取到发送消息后服务器的返回值,如果直接通过页面的弹窗获取发送消息后的结果会非常麻烦,有时候一个消息发送后会产生多种不同的返回结果,可能提交成功,可能提交失败,可能消息超时等等,如果能够直接获取到发送消息的Request,无疑会大大方便我们判断。

例如这是点击百度搜索框时产生的GET消息的返回值:

    CefSharp贴心的为开发者提供了网页运行的不同阶段的回调函数,类似于VUE前端框架的钩子函数。CefSharp允许开发者在POST或GET消息发送时修改提交的参数也就是postData,还可以拦截修改图片,JS文件,CSS样式等等,这篇文章只是记录如何获取GET或者POST消息提交后直接获取JSON、XML、HTML数据。

这些自定义功能都基于IResourceRequestHandler类,首先我们要创建一个新的类继承重写这个类中的方法。

public class ResourceRequestHandler : IResourceRequestHandler
    {
        /// <summary>
        /// Called on the CEF IO thread before a resource request is loaded. To optionally filter cookies for the request return a
        /// <see cref="ICookieAccessFilter"/> object.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - can be modified in this callback.</param>
        /// <returns>To optionally filter cookies for the request return a ICookieAccessFilter instance otherwise return null.</returns>
        ICookieAccessFilter IResourceRequestHandler.GetCookieAccessFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request)
        {
            return GetCookieAccessFilter(chromiumWebBrowser, browser, frame, request);
        }

        /// <summary>
        /// Called on the CEF IO thread before a resource request is loaded. To optionally filter cookies for the request return a
        /// <see cref="ICookieAccessFilter"/> object.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - can be modified in this callback.</param>
        /// <returns>To optionally filter cookies for the request return a ICookieAccessFilter instance otherwise return null.</returns>
        protected virtual ICookieAccessFilter GetCookieAccessFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request)
        {
            return null;
        }

        /// <summary>
        /// Called on the CEF IO thread before a resource is loaded. To specify a handler for the resource return a
        /// <see cref="IResourceHandler"/> object.
        /// </summary>
        /// <param name="chromiumWebBrowser">The browser UI control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - cannot be modified in this callback.</param>
        /// <returns>
        /// To allow the resource to load using the default network loader return null otherwise return an instance of
        /// <see cref="IResourceHandler"/> with a valid stream.
        /// </returns>
        IResourceHandler IResourceRequestHandler.GetResourceHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request)
        {
            return GetResourceHandler(chromiumWebBrowser, browser, frame, request);
        }

        /// <summary>
        /// Called on the CEF IO thread before a resource is loaded. To specify a handler for the resource return a
        /// <see cref="IResourceHandler"/> object.
        /// </summary>
        /// <param name="chromiumWebBrowser">The browser UI control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - cannot be modified in this callback.</param>
        /// <returns>
        /// To allow the resource to load using the default network loader return null otherwise return an instance of
        /// <see cref="IResourceHandler"/> with a valid stream.
        /// </returns>
        protected virtual IResourceHandler GetResourceHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request)
        {
            return null;
        }

        /// <summary>Called on the CEF IO thread to optionally filter resource response content.</summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - cannot be modified in this callback.</param>
        /// <param name="response">the response object - cannot be modified in this callback.</param>
        /// <returns>Return an IResponseFilter to intercept this response, otherwise return null.</returns>
        IResponseFilter IResourceRequestHandler.GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
        {
            return GetResourceResponseFilter(chromiumWebBrowser, browser, frame, request, response);
        }

        /// <summary>Called on the CEF IO thread to optionally filter resource response content.</summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - cannot be modified in this callback.</param>
        /// <param name="response">the response object - cannot be modified in this callback.</param>
        /// <returns>Return an IResponseFilter to intercept this response, otherwise return null.</returns>
        protected virtual IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
        {
            return null;
        }

        /// <summary>
        /// Called on the CEF IO thread before a resource request is loaded. To redirect or change the resource load optionally modify
        /// <paramref name="request"/>. Modification of the request URL will be treated as a redirect.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - can be modified in this callback.</param>
        /// <param name="callback">Callback interface used for asynchronous continuation of url requests.</param>
        /// <returns>
        /// Return <see cref="CefReturnValue.Continue"/> to continue the request immediately. Return
        /// <see cref="CefReturnValue.ContinueAsync"/> and call <see cref="IRequestCallback.Continue"/> or
        /// <see cref="IRequestCallback.Cancel"/> at a later time to continue or the cancel the request asynchronously. Return
        /// <see cref="CefReturnValue.Cancel"/> to cancel the request immediately.
        /// </returns>
        CefReturnValue IResourceRequestHandler.OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
        {
            return OnBeforeResourceLoad(chromiumWebBrowser, browser, frame, request, callback);
        }

        /// <summary>
        /// Called on the CEF IO thread before a resource request is loaded. To redirect or change the resource load optionally modify
        /// <paramref name="request"/>. Modification of the request URL will be treated as a redirect.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - can be modified in this callback.</param>
        /// <param name="callback">Callback interface used for asynchronous continuation of url requests.</param>
        /// <returns>
        /// Return <see cref="CefReturnValue.Continue"/> to continue the request immediately. Return
        /// <see cref="CefReturnValue.ContinueAsync"/> and call <see cref="IRequestCallback.Continue"/> or
        /// <see cref="IRequestCallback.Cancel"/> at a later time to continue or the cancel the request asynchronously. Return
        /// <see cref="CefReturnValue.Cancel"/> to cancel the request immediately.
        /// </returns>
        protected virtual CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
        {
            return CefReturnValue.Continue;
        }

        /// <summary>
        /// Called on the CEF UI thread to handle requests for URLs with an unknown protocol component. SECURITY WARNING: YOU SHOULD USE
        /// THIS METHOD TO ENFORCE RESTRICTIONS BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - cannot be modified in this callback.</param>
        /// <returns>
        /// return to true to attempt execution via the registered OS protocol handler, if any. Otherwise return false.
        /// </returns>
        bool IResourceRequestHandler.OnProtocolExecution(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request)
        {
            return OnProtocolExecution(chromiumWebBrowser, browser, frame, request);
        }

        /// <summary>
        /// Called on the CEF UI thread to handle requests for URLs with an unknown protocol component. SECURITY WARNING: YOU SHOULD USE
        /// THIS METHOD TO ENFORCE RESTRICTIONS BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - cannot be modified in this callback.</param>
        /// <returns>
        /// return to true to attempt execution via the registered OS protocol handler, if any. Otherwise return false.
        /// </returns>
        protected virtual bool OnProtocolExecution(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request)
        {
            return false;
        }

        /// <summary>
        /// Called on the CEF IO thread when a resource load has completed. This method will be called for all requests, including
        /// requests that are aborted due to CEF shutdown or destruction of the associated browser. In cases where the associated browser
        /// is destroyed this callback may arrive after the <see cref="ILifeSpanHandler.OnBeforeClose"/> callback for that browser. The
        /// <see cref="IFrame.IsValid"/> method can be used to test for this situation, and care
        /// should be taken not to call <paramref name="browser"/> or <paramref name="frame"/> methods that modify state (like LoadURL,
        /// SendProcessMessage, etc.) if the frame is invalid.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - cannot be modified in this callback.</param>
        /// <param name="response">the response object - cannot be modified in this callback.</param>
        /// <param name="status">indicates the load completion status.</param>
        /// <param name="receivedContentLength">is the number of response bytes actually read.</param>
        void IResourceRequestHandler.OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
        {
            OnResourceLoadComplete(chromiumWebBrowser, browser, frame, request, response, status, receivedContentLength);
        }

        /// <summary>
        /// Called on the CEF IO thread when a resource load has completed. This method will be called for all requests, including
        /// requests that are aborted due to CEF shutdown or destruction of the associated browser. In cases where the associated browser
        /// is destroyed this callback may arrive after the <see cref="ILifeSpanHandler.OnBeforeClose"/> callback for that browser. The
        /// <see cref="IFrame.IsValid"/> method can be used to test for this situation, and care
        /// should be taken not to call <paramref name="browser"/> or <paramref name="frame"/> methods that modify state (like LoadURL,
        /// SendProcessMessage, etc.) if the frame is invalid.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - cannot be modified in this callback.</param>
        /// <param name="response">the response object - cannot be modified in this callback.</param>
        /// <param name="status">indicates the load completion status.</param>
        /// <param name="receivedContentLength">is the number of response bytes actually read.</param>
        protected virtual void OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
        {

        }

        /// <summary>
        /// Called on the CEF IO thread when a resource load is redirected. The <paramref name="request"/> parameter will contain the old
        /// URL and other request-related information. The <paramref name="response"/> parameter will contain the response that resulted
        /// in the redirect. The <paramref name="newUrl"/> parameter will contain the new URL and can be changed if desired.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - cannot be modified in this callback.</param>
        /// <param name="response">the response object - cannot be modified in this callback.</param>
        /// <param name="newUrl">[in,out] the new URL and can be changed if desired.</param>
        void IResourceRequestHandler.OnResourceRedirect(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl)
        {
            OnResourceRedirect(chromiumWebBrowser, browser, frame, request, response, ref newUrl);
        }

        /// <summary>
        /// Called on the CEF IO thread when a resource load is redirected. The <paramref name="request"/> parameter will contain the old
        /// URL and other request-related information. The <paramref name="response"/> parameter will contain the response that resulted
        /// in the redirect. The <paramref name="newUrl"/> parameter will contain the new URL and can be changed if desired.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object - cannot be modified in this callback.</param>
        /// <param name="response">the response object - cannot be modified in this callback.</param>
        /// <param name="newUrl">[in,out] the new URL and can be changed if desired.</param>
        protected virtual void OnResourceRedirect(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl)
        {

        }

        /// <summary>
        /// Called on the CEF IO thread when a resource response is received. To allow the resource load to proceed without modification
        /// return false. To redirect or retry the resource load optionally modify <paramref name="request"/> and return true.
        /// Modification of the request URL will be treated as a redirect. Requests handled using the default network loader cannot be
        /// redirected in this callback.
        /// 
        /// WARNING: Redirecting using this method is deprecated. Use OnBeforeResourceLoad or GetResourceHandler to perform redirects.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object.</param>
        /// <param name="response">the response object - cannot be modified in this callback.</param>
        /// <returns>
        /// To allow the resource load to proceed without modification return false. To redirect or retry the resource load optionally
        /// modify <paramref name="request"/> and return true. Modification of the request URL will be treated as a redirect. Requests
        /// handled using the default network loader cannot be redirected in this callback.
        /// </returns>
        bool IResourceRequestHandler.OnResourceResponse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
        {
            return OnResourceResponse(chromiumWebBrowser, browser, frame, request, response);
        }

        /// <summary>
        /// Called on the CEF IO thread when a resource response is received. To allow the resource load to proceed without modification
        /// return false. To redirect or retry the resource load optionally modify <paramref name="request"/> and return true.
        /// Modification of the request URL will be treated as a redirect. Requests handled using the default network loader cannot be
        /// redirected in this callback.
        /// 
        /// WARNING: Redirecting using this method is deprecated. Use OnBeforeResourceLoad or GetResourceHandler to perform redirects.
        /// </summary>
        /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
        /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
        /// <param name="request">the request object.</param>
        /// <param name="response">the response object - cannot be modified in this callback.</param>
        /// <returns>
        /// To allow the resource load to proceed without modification return false. To redirect or retry the resource load optionally
        /// modify <paramref name="request"/> and return true. Modification of the request URL will be treated as a redirect. Requests
        /// handled using the default network loader cannot be redirected in this callback.
        /// </returns>
        protected virtual bool OnResourceResponse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
        {
            return false;
        }

        /// <summary>
        /// Called when the unamanged resource is freed.
        /// Unmanaged resources are ref counted and freed when
        /// the last reference is released, this works differently
        /// to .Net garbage collection.
        /// </summary>
        protected virtual void Dispose()
        {

        }

        void IDisposable.Dispose()
        {
            Dispose();
        }
    }

然后获取消息发送后的返回值则是在IResponseFilter类的方法中接收,也新建一个类继承IResponseFilter类。

public class TestJsonFilter : IResponseFilter
    {
        public List<byte> DataAll = new List<byte>();

        public FilterStatus Filter(System.IO.Stream dataIn, out long dataInRead, System.IO.Stream dataOut, out long dataOutWritten)
        {
            try
            {
                if (dataIn == null || dataIn.Length == 0)
                {
                    dataInRead = 0;
                    dataOutWritten = 0;

                    return FilterStatus.Done;
                }

                dataInRead = dataIn.Length;
                dataOutWritten = Math.Min(dataInRead, dataOut.Length);

                dataIn.CopyTo(dataOut);
                dataIn.Seek(0, SeekOrigin.Begin);
                byte[] bs = new byte[dataIn.Length];
                dataIn.Read(bs, 0, bs.Length);
                DataAll.AddRange(bs);

                dataInRead = dataIn.Length;
                dataOutWritten = dataIn.Length;

                return FilterStatus.NeedMoreData;
            }
            catch (Exception ex)
            {
                dataInRead = dataIn.Length;
                dataOutWritten = dataIn.Length;

                return FilterStatus.Done;
            }
        }

        public bool InitFilter()
        {
            return true;
        }

        public void Dispose()
        {

        }
    }

再创建一个类用于配合读取返回值。

    public class FilterManager
    {
        private static Dictionary<string, IResponseFilter> dataList = new Dictionary<string, IResponseFilter>();

        public static IResponseFilter CreateFilter(string guid)
        {
            lock (dataList)
            {
                var filter = new TestJsonFilter();
                dataList.Add(guid, filter);

                return filter;
            }
        }

        public static IResponseFilter GetFileter(string guid)
        {
            lock (dataList)
            {
                return dataList[guid];
            }
        }
    }

然后重写IResponseFilter、OnResourceLoadComplete两个接口,在OnResourceLoadComplete接口中就能接收返回值了。返回值会返回到函数的request参数下,此参数是一个结构体,可以自行在 if (request.Url.ToLower().Contains("sugrec")) 这一句上下断点查看结构体的内容,然后自行加判断来过滤返回值,这里鄙人先判断发送类型为GET消息,然后再根据发送消息URL里的关键字来过滤返回值,最后显示到WinForm窗口程序绑定的控制台窗口里。

    public class WinFormResourceRequestHandler : ResourceRequestHandler
    {
        protected override IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
        {
            var filter = FilterManager.CreateFilter(request.Identifier.ToString());
            return filter;
        }

        protected override void OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
        {


            if (request.Method == "GET")
            {
                //先指定消息类型POST或者GET
                if (request.Url.ToLower().Contains("sugrec"))
                {
                    //以URL为过滤条件

                    var filter = FilterManager.GetFileter(request.Identifier.ToString()) as TestJsonFilter;
                    UTF8Encoding encoding = new UTF8Encoding();
                    //这里截获返回的数据
                    var data = encoding.GetString(filter.DataAll.ToArray());

                    System.Console.WriteLine("742行:" + data);
                }

            }


        }


    }


    public class WinFormsRequestHandler : RequestHandler
    {
        protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
        {
            //NOTE: In most cases you examine the request.Url and only handle requests you are interested in
            if (request.Url.ToLower().Contains("login".ToLower()))
            {
                using (var postData = request.PostData)
                {
                    if (postData != null)
                    {
                        var elements = postData.Elements;

                        var charSet = request.GetCharSet();

                        foreach (var element in elements)
                        {
                            if (element.Type == PostDataElementType.Bytes)
                            {
                                var body = element.GetBody(charSet);
                            }
                        }
                    }
                }
            }
            return new WinFormResourceRequestHandler();
        }

    }

运行程序后:

如何运用这个自定义的类呢?

using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
using CefSharp.Handler;
using System.Runtime.InteropServices;
using System.Threading;
using System.Text.RegularExpressions;
using System.Security.Cryptography.X509Certificates;
using System.IO;


public partial class Form1 : Form
{

        ChromiumWebBrowser different;


        [DllImport("kernel32.dll")]
        public static extern bool AllocConsole();
        [DllImport("kernel32.dll")]
        public static extern bool FreeConsole();

        public Form1()
        {
            InitializeComponent();
            AllocConsole(); //关联一个控制台窗口用于显示信息
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
            CefSettings settings = new CefSettings();

            settings.CachePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Know";
            //设置cookie存储目录 C:\Users\×××(系统用户名)\AppData\Local\Know

            Cef.Initialize(settings);//初始化Cef组件

            different = new ChromiumWebBrowser("https://www.baidu.com");
    
            different.RequestHandler = new WinFormsRequestHandler();//应用拦截规则
            different.LifeSpanHandler = new CefLifeSpanHandler();//让新页面在当前页面打开

            different.BrowserSettings = new BrowserSettings()
            {
                WebGl = CefState.Enabled,
                ImageLoading = CefState.Enabled,
                RemoteFonts = CefState.Enabled,
                AcceptLanguageList = "zh-CN"
            };


            tableLayoutPanel1.Controls.Add(different, 0, 1);//把浏览器空间加入布局容器
            

        }

       private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //窗口关闭前 回调函数
            FreeConsole();//释放关联的控制台,不然会报错

        }


}

参考资料:https://www.cnblogs.com/heifengwll/p/13277232.html

如何拦截替换页面资源,JS,CSS等:CefSharp请求资源拦截及自定义处理-腾讯云开发者社区-腾讯云

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/217899.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Azure]azure磁盘加密(Windows/Linux) ADE(Azure Disk Encryption)

Azure 磁盘加密用于保护数据&#xff0c;对于Windows使用BitLocker对磁盘进行加密&#xff0c;同时与Key Vault集成&#xff0c;控制和管理Key和Secret。 本文利用Potal对磁盘进行加密 注&#xff1a;Azure DIsk Encryption 可能会导致VM重启&#xff0c;对VM造成影响&#xff…

哈希与哈希表

哈希表的概念 哈希表又名散列表&#xff0c;官话一点讲就是&#xff1a; 散列表&#xff08;Hash table&#xff0c;也叫哈希表&#xff09;&#xff0c;是根据关键码值(Key value)而直接进行访问的数据结构。也就是说&#xff0c;它通过把关键码值映射到表中一个位置来访问记…

基于SSM的老年公寓信息管理的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

nodejs微信小程序+python+PHP天天网站书城管理系统的设计与实现-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

QT 中 QMessageBox 的简单用法

效果 思路 // 创建一个question弹出对话框&#xff0c;添加两个按钮&#xff1a;Yes和NoQMessageBox *box new QMessageBox(QMessageBox::Question, "提示", "确认删除的信息吗&#xff1f;", QMessageBox::Yes | QMessageBox::No, this);box->button(…

成人学生钢笔练字快速入门,硬笔书法行书楷书教程合集

一、教程描述 虽然现在都是电脑打字&#xff0c;需要手写的场合越来越少&#xff0c;但是可以写一手人见人爱&#xff0c;花见花开的好字&#xff0c;仍然是很拉风很惊艳的&#xff0c;可以给人留下深刻印象。本套硬笔书法教程&#xff0c;大小40.90G&#xff0c;共有591个文件…

Python 网络爬虫(二):HTTP 基础知识

《Python入门核心技术》专栏总目录・点这里 文章目录 1. HTTP 协议简述2. HTTP 请求过程3. HTTP 的结构3.1 请求行3.2 请求头3.3 请求体3.4 状态行3.5 响应头3.6 响应体 4. Cookie 状态管理5. HTTP 请求示例6. 总结 大家好&#xff0c;我是水滴~~ 在准备学习网络爬虫之前&…

公有云迁移研究——AWS Route53

大纲 1 什么是Route 532 Route 53能做些什么# 3 通过DNS托管来实现分流3.1 创建DNS托管3.2 对托管创建记录对流量进行分配 4 通过流量策略来对流量进行分流4.1 创建流量策略 5 对比两者的区别6 推荐 在给客户从本地机房往AWS迁移的过程中&#xff0c;我们接到如下需求&#xff…

vue打印功能

安装 vue3-print-nb yarn add vue3-print-nb //或 npm install vue3-print-nb main.js中引入 vue3-print-nb import { createApp } from vue; import App from ./App.vue; const app createApp(App); // 打印插件 import print from vue3-print-nb app.use(print) // 页面…

公有云迁移研究——AWS Translate

大纲 1 什么是Translate2 Aws Translate是怎么运作的3 Aws Translate和Google Translate的区别4 迁移任务4.1 迁移原因 5 Aws Translate的Go demo6 迁移中遇到的问题6.1 账号和权限问题&#xff1a;6.2 小语种 1 什么是Translate Translate是一种文本翻译服务&#xff0c;它使…

制作一个RISC-V的操作系统三-编译与链接

文章目录 GCCGCC简介GCC的命令格式gcc -Egcc -cgcc -Sgcc -ggcc -vGCC的主要执行步骤GCC涉及的文件类型针对多个源文件的处理 ELFELF介绍ELF文件格式ELF文件处理相关工具&#xff1a;Binutils&#xff08;binary utility&#xff09;readlelf -hreadelf -S或readelf -SW&#x…

思维模型 路径依赖定律

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。难以摆脱的惯性。 1 路径依赖定律的应用 1.1 打破路径依赖定律的苹果 在 20 世纪 80 年代&#xff0c;苹果公司推出了 Macintosh 电脑&#xff0c;这是一款具有图形用户界面和鼠标的创新产…

MacOS M芯片 安装MySQL5.7教程

目录 1. 安装Homebrew1.1 快速安装1.2 检查是否安装成功 2. 通过Homebrew安装MySQL2.1 搜索 MySQL 版本2.2 安装MySQL 5.72.3 位置说明2.4 启动MySQL服务2.5 检查服务状态2.6 设置环境变量2.7 重置密码 3. 测试安装 1. 安装Homebrew 1.1 快速安装 /bin/bash -c "$(curl …

SQL Server 数据库,多表查询

4.2使用T-SQL实现多表查询 前面讲述过的所有查询都是基于单个数据库表的查询&#xff0c;如果一个查询需要对多个表进行操作&#xff0c; 就称为联接查询&#xff0c;联接查询的结果集或结果称为表之间的联接。 联接查询实际上是通过各个表之间共同列的关联性来查询数据的&…

人工智能|网络爬虫——用Python爬取电影数据并可视化分析

一、获取数据 1.技术工具 IDE编辑器&#xff1a;vscode 发送请求&#xff1a;requests 解析工具&#xff1a;xpath def Get_Detail(Details_Url):Detail_Url Base_Url Details_UrlOne_Detail requests.get(urlDetail_Url, headersHeaders)One_Detail_Html One_Detail.cont…

后端部署-阿里云服务器-开设端口-域名解析-安全证书-备案

本文以阿里云的轻量级数据库为例子。 前言 要搭建一个完整的后端系统一般的步骤&#xff1a; 获得一台服务器----->开设端口----->搭建后台所需要的语言和应用---->利用公网ip地址测试后端程序------->购买域名和证书-------->域名绑定和解析------->icp备…

同源策略与跨域

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 不论个人练习还是实际开…

【JUC】二十、volatile变量的特点与使用场景

文章目录 1、volatile可见性案例2、线程工作内存与主内存之间的原子操作3、volatile变量不具有原子性案例4、无原子性的原因分析&#xff1a;i5、volatile变量小总结6、重排序7、volatile变量禁重排的案例8、日常使用场景9、总结 volatile变量的特点&#xff1a; 可见性禁重排无…

如何利用企业软件著作权查询API提升知识产权管理效率

引言 在当今数字化时代&#xff0c;企业的知识产权管理变得愈发重要。其中&#xff0c;软件著作权作为企业重要的知识产权之一&#xff0c;其保护和管理对于企业的创新和竞争力至关重要。为了更高效地进行软件著作权管理&#xff0c;许多企业开始采用先进的技术手段&#xff0…

Chrome清除特定网站的Cookie,从而让网址能正常运行(例如GPT)

Chrome在使用某些网址的时候&#xff0c;例如GPT的时候&#xff0c;可能会出现无法访问这个网址的情况&#xff0c;就是点不动啥的 只需要把你需要重置的网址删除就好了
最新文章