CefSharp過濾圖片RequestHandler問題
C# CefSharp 過濾 RequestHandler 圖片
1、方式一
ChromiumWebBrowser 實現(xiàn) IRequestHandler
具體內(nèi)同參照 附錄;將 OnBeforeResourceLoad方法替換成2中的內(nèi)容,很簡單;
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; ? ? ? ? } }
對比實現(xiàn)接口方式和繼承集成默認的抽象類,發(fā)現(xiàn)抽象類可以只實現(xiàn)相關(guān)的處理方法更加靈活。而若采用IRequestHandler需要實現(xiàn)RequestHandler接口中的所有方法,否則拋出未實現(xiàn)異常;
和其他網(wǎng)上從Response環(huán)節(jié)過濾資源圖片的方法不同,這里談到的方法在請求圖片資源之前,可以節(jié)省流量,加快頁面訪問速度等。
附錄:
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 + "http://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); } } } } }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
DevExpress實現(xiàn)根據(jù)行,列索引來獲取RepositoryItem的方法
這篇文章主要介紹了DevExpress實現(xiàn)根據(jù)行,列索引來獲取RepositoryItem的方法,需要的朋友可以參考下2014-08-08c# 免費組件html轉(zhuǎn)pdf的實現(xiàn)過程
這篇文章主要介紹了c# 免費組件html轉(zhuǎn)pdf的實現(xiàn)過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06