源码地址:源代码csdn 或者底部qq问我要
五、cefsharp拦截response数据
与四类似,response数据也是要继承接口 IResourceRequestHandler,实现其方法,从方法中获取
1、添加类ResourceRequestHandler,继承IResourceRequestHandler,实现各种方法
public class ResourceRequestHandler : IResourceRequestHandler
{
/// <summary>
/// Called on the CEF IO thread before a resource request is loaded. To optionally filter cookies for the request return a
/// <see cref="ICookieAccessFilter"/> object.
/// </summary>
/// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param>
/// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param>
/// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param>
/// <param name="request">the request object - can be modified in this callback.</param>
/// <returns>To optionally filter cookies for the request return a ICookieAccessFilter instance otherwise return null.</returns>
ICookieAccessFilter IResourceRequestHandler.GetCookieAccessFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request) { return GetCookieAccessFilter(chromiumWebBrowser, browser, frame, request); } /// <summary> /// Called on the CEF IO thread before a resource request is loaded. To optionally filter cookies for the request return a /// <see cref="ICookieAccessFilter"/> object. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - can be modified in this callback.</param> /// <returns>To optionally filter cookies for the request return a ICookieAccessFilter instance otherwise return null.</returns> protected virtual ICookieAccessFilter GetCookieAccessFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request) { return null; } /// <summary> /// Called on the CEF IO thread before a resource is loaded. To specify a handler for the resource return a /// <see cref="IResourceHandler"/> object. /// </summary> /// <param name="chromiumWebBrowser">The browser UI control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - cannot be modified in this callback.</param> /// <returns> /// To allow the resource to load using the default network loader return null otherwise return an instance of /// <see cref="IResourceHandler"/> with a valid stream. /// </returns> IResourceHandler IResourceRequestHandler.GetResourceHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request) { return GetResourceHandler(chromiumWebBrowser, browser, frame, request); } /// <summary> /// Called on the CEF IO thread before a resource is loaded. To specify a handler for the resource return a /// <see cref="IResourceHandler"/> object. /// </summary> /// <param name="chromiumWebBrowser">The browser UI control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - cannot be modified in this callback.</param> /// <returns> /// To allow the resource to load using the default network loader return null otherwise return an instance of /// <see cref="IResourceHandler"/> with a valid stream. /// </returns> protected virtual IResourceHandler GetResourceHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request) { return null; } /// <summary>Called on the CEF IO thread to optionally filter resource response content.</summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - cannot be modified in this callback.</param> /// <param name="response">the response object - cannot be modified in this callback.</param> /// <returns>Return an IResponseFilter to intercept this response, otherwise return null.</returns> IResponseFilter IResourceRequestHandler.GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response) { return GetResourceResponseFilter(chromiumWebBrowser, browser, frame, request, response); } /// <summary>Called on the CEF IO thread to optionally filter resource response content.</summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - cannot be modified in this callback.</param> /// <param name="response">the response object - cannot be modified in this callback.</param> /// <returns>Return an IResponseFilter to intercept this response, otherwise return null.</returns> protected virtual IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response) { return null; } /// <summary> /// Called on the CEF IO thread before a resource request is loaded. To redirect or change the resource load optionally modify /// <paramref name="request"/>. Modification of the request URL will be treated as a redirect. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - can be modified in this callback.</param> /// <param name="callback">Callback interface used for asynchronous continuation of url requests.</param> /// <returns> /// Return <see cref="CefReturnValue.Continue"/> to continue the request immediately. Return /// <see cref="CefReturnValue.ContinueAsync"/> and call <see cref="IRequestCallback.Continue"/> or /// <see cref="IRequestCallback.Cancel"/> at a later time to continue or the cancel the request asynchronously. Return /// <see cref="CefReturnValue.Cancel"/> to cancel the request immediately. /// </returns> CefReturnValue IResourceRequestHandler.OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) { return OnBeforeResourceLoad(chromiumWebBrowser, browser, frame, request, callback); } /// <summary> /// Called on the CEF IO thread before a resource request is loaded. To redirect or change the resource load optionally modify /// <paramref name="request"/>. Modification of the request URL will be treated as a redirect. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - can be modified in this callback.</param> /// <param name="callback">Callback interface used for asynchronous continuation of url requests.</param> /// <returns> /// Return <see cref="CefReturnValue.Continue"/> to continue the request immediately. Return /// <see cref="CefReturnValue.ContinueAsync"/> and call <see cref="IRequestCallback.Continue"/> or /// <see cref="IRequestCallback.Cancel"/> at a later time to continue or the cancel the request asynchronously. Return /// <see cref="CefReturnValue.Cancel"/> to cancel the request immediately. /// </returns> protected virtual CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) { return CefReturnValue.Continue; } /// <summary> /// Called on the CEF UI thread to handle requests for URLs with an unknown protocol component. SECURITY WARNING: YOU SHOULD USE /// THIS METHOD TO ENFORCE RESTRICTIONS BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - cannot be modified in this callback.</param> /// <returns> /// return to true to attempt execution via the registered OS protocol handler, if any. Otherwise return false. /// </returns> bool IResourceRequestHandler.OnProtocolExecution(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request) { return OnProtocolExecution(chromiumWebBrowser, browser, frame, request); } /// <summary> /// Called on the CEF UI thread to handle requests for URLs with an unknown protocol component. SECURITY WARNING: YOU SHOULD USE /// THIS METHOD TO ENFORCE RESTRICTIONS BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - cannot be modified in this callback.</param> /// <returns> /// return to true to attempt execution via the registered OS protocol handler, if any. Otherwise return false. /// </returns> protected virtual bool OnProtocolExecution(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request) { return false; } /// <summary> /// Called on the CEF IO thread when a resource load has completed. This method will be called for all requests, including /// requests that are aborted due to CEF shutdown or destruction of the associated browser. In cases where the associated browser /// is destroyed this callback may arrive after the <see cref="ILifeSpanHandler.OnBeforeClose"/> callback for that browser. The /// <see cref="IFrame.IsValid"/> method can be used to test for this situation, and care /// should be taken not to call <paramref name="browser"/> or <paramref name="frame"/> methods that modify state (like LoadURL, /// SendProcessMessage, etc.) if the frame is invalid. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - cannot be modified in this callback.</param> /// <param name="response">the response object - cannot be modified in this callback.</param> /// <param name="status">indicates the load completion status.</param> /// <param name="receivedContentLength">is the number of response bytes actually read.</param> void IResourceRequestHandler.OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength) { OnResourceLoadComplete(chromiumWebBrowser, browser, frame, request, response, status, receivedContentLength); } /// <summary> /// Called on the CEF IO thread when a resource load has completed. This method will be called for all requests, including /// requests that are aborted due to CEF shutdown or destruction of the associated browser. In cases where the associated browser /// is destroyed this callback may arrive after the <see cref="ILifeSpanHandler.OnBeforeClose"/> callback for that browser. The /// <see cref="IFrame.IsValid"/> method can be used to test for this situation, and care /// should be taken not to call <paramref name="browser"/> or <paramref name="frame"/> methods that modify state (like LoadURL, /// SendProcessMessage, etc.) if the frame is invalid. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - cannot be modified in this callback.</param> /// <param name="response">the response object - cannot be modified in this callback.</param> /// <param name="status">indicates the load completion status.</param> /// <param name="receivedContentLength">is the number of response bytes actually read.</param> protected virtual void OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength) { } /// <summary> /// Called on the CEF IO thread when a resource load is redirected. The <paramref name="request"/> parameter will contain the old /// URL and other request-related information. The <paramref name="response"/> parameter will contain the response that resulted /// in the redirect. The <paramref name="newUrl"/> parameter will contain the new URL and can be changed if desired. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - cannot be modified in this callback.</param> /// <param name="response">the response object - cannot be modified in this callback.</param> /// <param name="newUrl">[in,out] the new URL and can be changed if desired.</param> void IResourceRequestHandler.OnResourceRedirect(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl) { OnResourceRedirect(chromiumWebBrowser, browser, frame, request, response, ref newUrl); } /// <summary> /// Called on the CEF IO thread when a resource load is redirected. The <paramref name="request"/> parameter will contain the old /// URL and other request-related information. The <paramref name="response"/> parameter will contain the response that resulted /// in the redirect. The <paramref name="newUrl"/> parameter will contain the new URL and can be changed if desired. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object - cannot be modified in this callback.</param> /// <param name="response">the response object - cannot be modified in this callback.</param> /// <param name="newUrl">[in,out] the new URL and can be changed if desired.</param> protected virtual void OnResourceRedirect(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl) { } /// <summary> /// Called on the CEF IO thread when a resource response is received. To allow the resource load to proceed without modification /// return false. To redirect or retry the resource load optionally modify <paramref name="request"/> and return true. /// Modification of the request URL will be treated as a redirect. Requests handled using the default network loader cannot be /// redirected in this callback. /// /// WARNING: Redirecting using this method is deprecated. Use OnBeforeResourceLoad or GetResourceHandler to perform redirects. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object.</param> /// <param name="response">the response object - cannot be modified in this callback.</param> /// <returns> /// To allow the resource load to proceed without modification return false. To redirect or retry the resource load optionally /// modify <paramref name="request"/> and return true. Modification of the request URL will be treated as a redirect. Requests /// handled using the default network loader cannot be redirected in this callback. /// </returns> bool IResourceRequestHandler.OnResourceResponse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response) { return OnResourceResponse(chromiumWebBrowser, browser, frame, request, response); } /// <summary> /// Called on the CEF IO thread when a resource response is received. To allow the resource load to proceed without modification /// return false. To redirect or retry the resource load optionally modify <paramref name="request"/> and return true. /// Modification of the request URL will be treated as a redirect. Requests handled using the default network loader cannot be /// redirected in this callback. /// /// WARNING: Redirecting using this method is deprecated. Use OnBeforeResourceLoad or GetResourceHandler to perform redirects. /// </summary> /// <param name="chromiumWebBrowser">The ChromiumWebBrowser control.</param> /// <param name="browser">the browser object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="frame">the frame object - may be null if originating from ServiceWorker or CefURLRequest.</param> /// <param name="request">the request object.</param> /// <param name="response">the response object - cannot be modified in this callback.</param> /// <returns> /// To allow the resource load to proceed without modification return false. To redirect or retry the resource load optionally /// modify <paramref name="request"/> and return true. Modification of the request URL will be treated as a redirect. Requests /// handled using the default network loader cannot be redirected in this callback. /// </returns> protected virtual bool OnResourceResponse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response) { return false; } /// <summary> /// Called when the unamanged resource is freed. /// Unmanaged resources are ref counted and freed when /// the last reference is released, this works differently /// to .Net garbage collection. /// </summary> protected virtual void Dispose() { } void IDisposable.Dispose() { Dispose(); } }
2、要从Resource Filter中获取数据,先添加两个类FilterManager、TestJsonFilter,合并在一个文件FilterManager中,用来获取数据
public class TestJsonFilter : IResponseFilter
{
public List<byte> DataAll = new List<byte>(); public FilterStatus Filter(System.IO.Stream dataIn, out long dataInRead, System.IO.Stream dataOut, out long dataOutWritten) { try { if (dataIn == null || dataIn.Length == 0) { dataInRead = 0; dataOutWritten = 0; return FilterStatus.Done; } dataInRead = dataIn.Length; dataOutWritten = Math.Min(dataInRead, dataOut.Length); dataIn.CopyTo(dataOut); dataIn.Seek(0, SeekOrigin.Begin); byte[] bs = new byte[dataIn.Length]; dataIn.Read(bs, 0, bs.Length); DataAll.AddRange(bs); dataInRead = dataIn.Length; dataOutWritten = dataIn.Length; return FilterStatus.NeedMoreData; } catch (Exception ex) { dataInRead = dataIn.Length; dataOutWritten = dataIn.Length; return FilterStatus.Done; } } public bool InitFilter() { return true; } public void Dispose() { } } public class FilterManager { private static Dictionary<string, IResponseFilter> dataList = new Dictionary<string, IResponseFilter>(); public static IResponseFilter CreateFilter(string guid) { lock (dataList) { var filter = new TestJsonFilter(); dataList.Add(guid, filter); return filter; } } public static IResponseFilter GetFileter(string guid) { lock (dataList) { return dataList[guid]; } } }
3、新建类WinFormResourceRequestHandler,继承ResourceRequestHandler类,重写覆盖父类方法GetResourceResponseFilter、OnResourceLoadComplete
public class WinFormResourceRequestHandler : ResourceRequestHandler { protected override IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response) { var filter = FilterManager.CreateFilter(request.Identifier.ToString()); return filter; } protected override void OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength) { if (request.Url.ToLower().Contains("login".ToLower())) { var filter = FilterManager.GetFileter(request.Identifier.ToString()) as TestJsonFilter; ASCIIEncoding encoding = new ASCIIEncoding(); //这里截获返回的数据 var data = encoding.GetString(filter.DataAll.ToArray()); } } }
此处也只拦截login登录返回的数据。也可以匹配别的页面请求
4、要修改IRequestHandler的实现类WinFormsRequestHandler中GetResourceRequestHandler方法,return null,改为return WinFormResourceRequestHandler,来调用请求后资源加载前的处理方法。
public class WinFormsRequestHandler : RequestHandler { protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling) { //NOTE: In most cases you examine the request.Url and only handle requests you are interested in if (request.Url.ToLower().Contains("login".ToLower())) { 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); } } } } } return new WinFormResourceRequestHandler(); } }
5、此时就可以调试运行,拦截获取到login请求后的的数据