就像谷歌浏览器的设置页面 是 chrome://settings/ 同样 , chrome 是他的 schemejavascript
这里参考https://qwqaq.com/ee43a4af.htmlcss
CefGule也提供了该功能的实现html
下面直接贴代码java
第一步 : 在 Debug 文件夹下建立目录 Pages/scheme 并建立 settings.html 文件(随便写点啥就能够)chrome
第二步 : 建立类文件 CefResourceHandler.cs 跨域
CefResourceHandler 用于处理用户对指定 Scheme 的请求,并返回响应数据浏览器
接口实现方法中只有前面那三个方法用到了cookie
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.csapp
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,固然你也能够改为其余的 } } } }
第四步 : 注册jsp
我在 Initialize 方法后注册的 , 好使
CefSettings settings = new CefSettings(); //... ... ... //运行库初始化 CefRuntime.Initialize(mainArgs, settings, cefApp); CefRuntime.RegisterSchemeHandlerFactory(SchemeHandlerFactory.SchemeName, "", new SchemeHandlerFactory());
第五步 : 而后你就能根据地址 qb://settings 请求到网页( Debug\Pages\\scheme\\settings.html )