CefGule 訪問嵌入的前端目錄:Scheme 自定義 + 文件夾做爲嵌入的資源

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

相關文章
相關標籤/搜索