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 请求到网页( Debug\Pages\\scheme\\settings.html )