• WinForm窗体程序中使用CefSharp获取加载后的资源、截取request参数、拦截response数据、注入jquery文件和js代码(3)-拦截response数据


    源码地址:源代码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请求后的的数据

  • 相关阅读:
    Linux Shell 基本语法
    VIM选择文本块/复制/粘贴
    linux vi命令详解2
    SSH命令详解2
    JAVA调用Shell脚本
    scp命令的用法详解
    Java实践 — SSH远程执行Shell脚本
    Remote SSH: Using JSCH with Expect4j
    c++内置函数---7
    c++将引用作为函数的参数---6
  • 原文地址:https://www.cnblogs.com/heifengwll/p/13277232.html
Copyright © 2020-2023  润新知