C# CefSharp 过滤 RequestHandler 图片
1、方式一
2、方式二
总结
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);
}
}
}
}
}
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持软件开发网。