就像谷歌瀏覽器的設置頁面 是 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 )