• CefGule 访问嵌入的前端目录:Scheme 自定义 + 文件夹作为嵌入的资源


    就像谷歌浏览器的设置页面 是 chrome://settings/ 一样 , chrome 是他的 scheme

    这里参考https://qwqaq.com/ee43a4af.html

    CefGule也提供了该功能的实现

    下面直接贴代码

    第一步 : 在 Debug 文件夹下创建目录 Pages/scheme 并创建  settings.html  文件(随便写点啥就可以)

    第二步 : 创建类文件 CefResourceHandler.cs 

    CefResourceHandler 用于处理用户对指定 Scheme 的请求,并返回响应数据

    接口实现方法中只有前面那三个方法用到了

    using CefBrowser.Config;
    using CefBrowser.Utils;
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Windows.Forms;
    using Xilium.CefGlue;
    
    namespace CefBrowser.Scheme
    {
        /// <summary>
        /// 【功能描述:Scheme处理类】
        /// 【创建时间:2019-8-6 15:27:40】
        /// </summary>
        class ResourceSchemeHandler : CefResourceHandler
        {
            private Uri uri;
    
            private string resourcePath;
    
            private bool resourceExist;
    
            private byte[] responseData;
    
            private long responseLength;//响应消息长度
    
            private int pos;
    
            /// <summary>
            /// Begin processing the request. To handle the request return true and call
            /// CefCallback::Continue() once the response header information is available
            /// (CefCallback::Continue() can also be called from inside this method if
            /// header information is available immediately). To cancel the request return
            /// false.
            /// 开始处理请求。
            /// 若要处理请求,请返回true,并在响应头信息可用时调用cefcallback::continue()
            /// (如果头信息立即可用,也可以从此方法内部调用cefcallback::continue())。
            /// 要取消请求,返回false。
            /// </summary>
            /// <param name="request"></param>
            /// <param name="callback"></param>
            /// <returns></returns>
            protected override bool ProcessRequest(CefRequest request, CefCallback callback)
            {
                var names = this.GetType().Assembly.GetManifestResourceNames();
                Console.WriteLine(names);
    
                uri = new Uri(request.Url);
                //uri.AbsolutePath
                string path = null;
                string scheme_path = BrowserPagesProxy.Instance.SchemePath;
                string scheme_suffix = BrowserPagesProxy.Instance.SchemeSuffix;
                if (uri.Scheme.Equals(SchemeHandlerFactory.SchemeName))
                {
                    if (BrowserPagesProxy.Instance.PagesArray.Contains(uri.OriginalString))
                    {
                        path = scheme_path + uri.Authority + "." + scheme_suffix;
                    }
                    else
                    {
                        path = scheme_path + uri.Authority + uri.AbsolutePath ;
                    }
                }
                else
                {
                    throw new Exception("Scheme不匹配");
                }
                resourcePath = Path.Combine(GlobalUtil.BasePath, path);
    
                Console.Write("resourcePath="+ resourcePath);
    
                resourceExist = File.Exists(resourcePath);
                if (resourceExist)
                {
                    FileStream fileStream = new FileStream(resourcePath, FileMode.Open, FileAccess.Read, FileShare.Read);
    
                    responseData = new byte[fileStream.Length];
    
                    fileStream.Read(responseData, 0, responseData.Length);
    
                    fileStream.Close();
    
                    responseLength = responseData.Length;
    
                }
                //TODO 处理文件不存在的情况
                
                callback.Continue();
                return true;
            }
    
            /// <summary>
            /// Read response data. If data is available immediately copy up to
            /// |bytes_to_read| bytes into |data_out|, set |bytes_read| to the number of
            /// bytes copied, and return true. To read the data at a later time set
            /// |bytes_read| to 0, return true and call CefCallback::Continue() when the
            /// data is available. To indicate response completion return false.
            /// 读取响应数据。
            /// 如果数据可用,立即将字节到字节复制到数据输出,将字节设置为复制的字节数,并返回true。
            /// 若要在以后读取数据,请将bytes_read_设置为0,返回true,并在数据可用时调用cefcallback::continue()。
            /// 指示响应完成返回 false。
            /// </summary>
            /// <param name="response"></param>
            /// <param name="bytesToRead"></param>
            /// <param name="bytesRead"></param>
            /// <param name="callback"></param>
            /// <returns></returns>
            protected override bool ReadResponse(Stream response, int bytesToRead, out int bytesRead, CefCallback callback)
            {
                bytesRead = 0;
    
                if (bytesToRead == 0 || responseLength==0 || pos >= responseData.Length)
                {
                    bytesRead = 0;
                    return false;
                }
                else
                {
                    response.Write(responseData, pos, bytesToRead);
                    pos += bytesToRead;
                    bytesRead = bytesToRead;
                    return true;
                }
            }
    
            /// <summary>
            /// Retrieve response header information. If the response length is not known
            /// set |response_length| to -1 and ReadResponse() will be called until it
            /// returns false. If the response length is known set |response_length|
            /// to a positive value and ReadResponse() will be called until it returns
            /// false or the specified number of bytes have been read. Use the |response|
            /// object to set the mime type, http status code and other optional header
            /// values. To redirect the request to a new URL set |redirectUrl| to the new
            /// URL.
            /// 检索响应头信息。
            /// 如果响应长度未知,则将响应长度设置为-1,并调用readResponse(),直到返回false。
            /// 如果已知响应长度,则将响应长度设置为正值,并将调用readResponse(),直到返回false或读取指定的字节数为止。
            /// 使用response对象设置mime类型、http状态代码和其他可选头值。
            /// 将请求重定向到新的URL集重定向URL到新的URL。
            /// </summary>
            /// <param name="response"></param>
            /// <param name="responseLength"></param>
            /// <param name="redirectUrl"></param>
            protected override void GetResponseHeaders(CefResponse response, out long responseLength, out string redirectUrl)
            {
                responseLength = this.responseLength;
    
                string mimeType = "application/octet-stream";
                switch (Path.GetExtension(resourcePath))
                {
                    case ".html":
                    case ".jsp":
                    case ".do":
                    case ".action":
                        mimeType = "text/html";
                        break;
                    case ".js":
                        mimeType = "text/javascript";
                        break;
                    case ".css":
                        mimeType = "text/css";
                        break;
                    case ".png":
                        mimeType = "image/png";
                        break;
                    case ".jpg":
                    case ".jpeg":
                        mimeType = "image/jpg";
                        break;
                    case ".appcache":
                        break;
                    case ".manifest":
                        mimeType = "text/cache-manifest";
                        break;
                }
                
                response.MimeType = mimeType;
                response.Status = 200;
                response.StatusText = "hello gdl !";
    
                var headers = new NameValueCollection(StringComparer.InvariantCultureIgnoreCase);
                headers.Add("Cache-Control", "private");
                headers.Add("Access - Control - Allow - Origin","*");//允许跨域
                response.SetHeaderMap(headers);
    
                
                redirectUrl = null;
    
            }
    
            #region 用不到的三个方法
            /// <summary>
            /// Request processing has been canceled.
            /// 请求处理已取消
            /// </summary>
            protected override void Cancel()
            {
            }
    
            /// <summary>
            /// 如果指定的cookie可以与请求一起发送,则返回true,否则返回false。
            /// 如果对任何cookie返回false,则不会随请求一起发送cookie
            /// </summary>
            /// <param name="cookie"></param>
            /// <returns></returns>
            protected override bool CanGetCookie(CefCookie cookie)
            {
                return false;
            }
    
            /// <summary>
            /// 如果可以设置随响应返回的指定cookie,则返回true;否则返回false。
            /// </summary>
            /// <param name="cookie"></param>
            /// <returns></returns>
            protected override bool CanSetCookie(CefCookie cookie)
            {
                return false;
            }
    
            #endregion
        }
    }

     第三步 : 创建工厂实例化类 SchemeHandlerFactory.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Xilium.CefGlue;
    
    namespace CefBrowser.Scheme
    {
        /// <summary>
        /// 【功能描述:Scheme处理类实例化工厂】
        /// 【创建时间:2019-8-6 16:15:23】
        /// </summary>
        class SchemeHandlerFactory : CefSchemeHandlerFactory
        {
            protected override CefResourceHandler Create(Xilium.CefGlue.CefBrowser browser, CefFrame frame, string schemeName, CefRequest request)
            {
                return new ResourceSchemeHandler();
            }
    
            public static string SchemeName
            {
                get
                {
                    return "qb"; // 这里我设置的 SchemeName 为 qb,当然你也可以改成其他的
                }
            }
        }
    }

    第四步 : 注册

    我在 Initialize 方法后注册的 , 好使

    CefSettings settings = new CefSettings();
    //... ... ...
    
    //运行库初始化
    CefRuntime.Initialize(mainArgs, settings, cefApp);
    
    CefRuntime.RegisterSchemeHandlerFactory(SchemeHandlerFactory.SchemeName, "", new SchemeHandlerFactory());

    第五步 : 然后你就能根据地址 qb://settings 请求到网页( DebugPages\scheme\settings.html )



  • 相关阅读:
    (一)RabbitMQ安装与基本配置
    一文搞懂网络层
    分布式锁的实现之 redis 篇
    浅谈synchronized和volatitle实现线程安全的策略
    JUC包的线程池详解
    Curling 2.0 POJ
    第三章处理机调度与死锁
    Java异常学习笔记
    Java对象学习笔记-下
    Java对象学习笔记-上
  • 原文地址:https://www.cnblogs.com/hi-gdl/p/11315309.html
Copyright © 2020-2023  润新知