CefSharp过滤图片RequestHandler问题

 

C# CefSharp 过滤 RequestHandler 图片

1、方式一

ChromiumWebBrowser 实现 IRequestHandler

具体内同参照 附录;将 OnBeforeResourceLoad方法替换成2中的内容,很简单;

2、方式二

继承集成默认的抽象类 DefaultRequestHandler

 internal class RequestHandler : DefaultRequestHandler 
    {

        public  override CefReturnValue  OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
        {

            if (request.ResourceType == ResourceType.Image)
                return CefReturnValue.Cancel;

            return CefReturnValue.Continue;
        }
}

对比实现接口方式和继承集成默认的抽象类,发现抽象类可以只实现相关的处理方法更加灵活。而若采用IRequestHandler需要实现RequestHandler接口中的所有方法,否则抛出未实现异常;

和其他网上从Response环节过滤资源图片的方法不同,这里谈到的方法在请求图片资源之前,可以节省流量,加快页面访问速度等。

附录:

using System;
using CefSharp.Example.Filters;
using System.Security.Cryptography.X509Certificates;
using System.Collections.Generic;
using System.Text;
using CefSharp.Handler;

namespace CefSharp.Example.Handlers
{
  /// <summary>
  /// DefaultRequestHandler provides a base class for you to inherit from 
  /// you only need to implement the methods that are relevant to you. 
  /// If you implement the IRequestHandler interface you will need to
  /// implement every method
  /// </summary>
  public class RequestHandler : IRequsetHandler
  {
      public static readonly string VersionNumberString = String.Format("Chromium: {0}, CEF: {1}, CefSharp: {2}",
          Cef.ChromiumVersion, Cef.CefVersion, Cef.CefSharpVersion);

      private Dictionary<UInt64, MemoryStreamResponseFilter> responseDictionary = new Dictionary<UInt64, MemoryStreamResponseFilter>();

      public override bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect)
      {
          return false;
      }

      public override bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture)
      {
          return false;
      }

      public override bool OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback)
      {
          //NOTE: If you do not wish to implement this method returning false is the default behaviour
          // We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
          //callback.Dispose();
          //return false;

          //NOTE: When executing the callback in an async fashion need to check to see if it's disposed
          if (!callback.IsDisposed)
          {
              using (callback)
              {
                  //To allow certificate
                  //callback.Continue(true);
                  //return true;
              }
          }

          return false;
      }

      public override void OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath)
      {
          // TODO: Add your own code here for handling scenarios where a plugin crashed, for one reason or another.
      }

      public override CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
      {
          Uri url;
          if (Uri.TryCreate(request.Url, UriKind.Absolute, out url) == false)
          {
              //If we're unable to parse the Uri then cancel the request
              // avoid throwing any exceptions here as we're being called by unmanaged code
              return CefReturnValue.Cancel;
          }

          //Example of how to set Referer
          // Same should work when setting any header

          // For this example only set Referer when using our custom scheme
          if (url.Scheme == CefSharpSchemeHandlerFactory.SchemeName)
          {
              //Referrer is now set using it's own method (was previously set in headers before)
              request.SetReferrer("http://google.com", ReferrerPolicy.Default);
          }

          //Example of setting User-Agent in every request.
          //var headers = request.Headers;

          //var userAgent = headers["User-Agent"];
          //headers["User-Agent"] = userAgent + " CefSharp";

          //request.Headers = headers;

          //NOTE: If you do not wish to implement this method returning false is the default behaviour
          // We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
          //callback.Dispose();
          //return false;

          //NOTE: When executing the callback in an async fashion need to check to see if it's disposed
          if (!callback.IsDisposed)
          {
              using (callback)
              {
                  if (request.Method == "POST")
                  {
                      using (var postData = request.PostData)
                      {
                          if(postData != null)
                          { 
                              var elements = postData.Elements;

                              var charSet = request.GetCharSet();

                              foreach (var element in elements)
                              {
                                  if (element.Type == PostDataElementType.Bytes)
                                  {
                                      var body = element.GetBody(charSet);
                                  }
                              }
                          }
                      }
                  }

                  //Note to Redirect simply set the request Url
                  //if (request.Url.StartsWith("https://www.google.com", StringComparison.OrdinalIgnoreCase))
                  //{
                  //    request.Url = "https://github.com/";
                  //}

                  //Callback in async fashion
                  //callback.Continue(true);
                  //return CefReturnValue.ContinueAsync;
              }
          }

          return CefReturnValue.Continue;
      }

      public override bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
      {
          //NOTE: If you do not wish to implement this method returning false is the default behaviour
          // We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.

          callback.Dispose();
          return false;
      }

      public override bool OnSelectClientCertificate(IWebBrowser browserControl, IBrowser browser, bool isProxy, string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback)
      {
          //NOTE: If you do not wish to implement this method returning false is the default behaviour
          // We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
          callback.Dispose();
          return false;
      }

      public override void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status)
      {
          // TODO: Add your own code here for handling scenarios where the Render Process terminated for one reason or another.
          browserControl.Load(CefExample.RenderProcessCrashedUrl);
      }

      public override bool OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize, IRequestCallback callback)
      {
          //NOTE: If you do not wish to implement this method returning false is the default behaviour
          // We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
          //callback.Dispose();
          //return false;

          //NOTE: When executing the callback in an async fashion need to check to see if it's disposed
          if (!callback.IsDisposed)
          {
              using (callback)
              {
                  //Accept Request to raise Quota
                  //callback.Continue(true);
                  //return true;
              }
          }

          return false;
      }

      public override void OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl)
      {
          //Example of how to redirect - need to check `newUrl` in the second pass
          //if (request.Url.StartsWith("https://www.google.com", StringComparison.OrdinalIgnoreCase) && !newUrl.Contains("github"))
          //{
          //    newUrl = "https://github.com";
          //}
      }

      public override bool OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url)
      {
          return url.StartsWith("mailto");
      }

      public override void OnRenderViewReady(IWebBrowser browserControl, IBrowser browser)
      {

      }

      public override bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
      {
          //NOTE: You cannot modify the response, only the request
          // You can now access the headers
          //var headers = response.Headers;

          return false;
      }

      public override IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
      {
          var url = new Uri(request.Url);
          if (url.Scheme == CefSharpSchemeHandlerFactory.SchemeName)
          {
              if(request.Url.Equals(CefExample.ResponseFilterTestUrl, StringComparison.OrdinalIgnoreCase))
              {
                  return new FindReplaceResponseFilter("REPLACE_THIS_STRING", "This is the replaced string!");
              }

              if (request.Url.Equals("custom://cefsharp/assets/js/jquery.js", StringComparison.OrdinalIgnoreCase))
              {
                  return new AppendResponseFilter(System.Environment.NewLine + "//CefSharp Appended this comment.");
              }

              //Only called for our customScheme
              var dataFilter = new MemoryStreamResponseFilter();
              responseDictionary.Add(request.Identifier, dataFilter);
              return dataFilter;
          }

          //return new PassThruResponseFilter();
          return null;
      }

      public override void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
      {
          var url = new Uri(request.Url);
          if (url.Scheme == CefSharpSchemeHandlerFactory.SchemeName)
          {
              MemoryStreamResponseFilter filter;
              if(responseDictionary.TryGetValue(request.Identifier, out filter))
              {
                  //TODO: Do something with the data here
                  var data = filter.Data;
                  var dataLength = filter.Data.Length;
                  //NOTE: You may need to use a different encoding depending on the request
                  var dataAsUtf8String = Encoding.UTF8.GetString(data);                
              }
          }
      }
  }
}

 

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程宝库

 前言用.net6开发一个Winform程序,处理Excel文件,并把结果导出Excel文件。要用到两个算法,一是turf.js库的booleanPointInPolygon方法,判断经纬度坐标是否在 ...