使用CefSharp捕获资源响应数据(正文)

Fri*_*oek 1 cefsharp

我正在尝试使用CefSharp访问URL并捕获在加载给定页面期间检索到的特定资源.大概是每个资源的Stream或byte数组.

CefSharp提供了接口IRequestHandler.您可以创建一个实现此接口的类来响应请求/响应事件,但它不以任何方式包含响应主体.

TEK*_*TEK 6

看一下GetResourceResponseFilter你的实现IRequestHandler.GetResourceResponseFilter返回一个IResponseFilter,它为您提供捕获所有响应的机会.你需要实现自己的IResponseFilter,幸好有很多例子.

IResponseFilterCefSharpGitHub项目中获取的示例实现.

public class MemoryStreamResponseFilter : IResponseFilter
{
        private MemoryStream memoryStream;

        bool IResponseFilter.InitFilter()
        {
            //NOTE: We could initialize this earlier, just one possible use of InitFilter
            memoryStream = new MemoryStream();

            return true;
        }

        FilterStatus IResponseFilter.Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten)
        {
            if (dataIn == null)
            {
                dataInRead = 0;
                dataOutWritten = 0;

                return FilterStatus.Done;
            }

            dataInRead = dataIn.Length;
            dataOutWritten = Math.Min(dataInRead, dataOut.Length);

            //Important we copy dataIn to dataOut
            dataIn.CopyTo(dataOut);

            //Copy data to stream
            dataIn.Position = 0;
            dataIn.CopyTo(memoryStream);

            return FilterStatus.Done;
        }

        void IDisposable.Dispose()
        {
            memoryStream.Dispose();
            memoryStream = null;
        }

        public byte[] Data
        {
            get { return memoryStream.ToArray(); }
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在在你的GetResourceResponseFilter方法中:

 private Dictionary<ulong, MemoryStreamResponseFilter> responseDictionary = new Dictionary<ulong, MemoryStreamResponseFilter>();
 public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
 {
       var dataFilter = new MemoryStreamResponseFilter();
       responseDictionary.Add(request.Identifier, dataFilter);
       return dataFilter;
 }
Run Code Online (Sandbox Code Playgroud)

然后进去 OnResourceLoadComplete

public void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
{      
    MemoryStreamResponseFilter filter;
    if (responseDictionary.TryGetValue(request.Identifier, out filter))
    {
        var data = filter.Data; //This returns a byte[]
        //File.WriteAllBytes("c:/save/path", data);
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用IRequestIResponse参数中的属性来判断要过滤的内容.

  • CefSharp 现在有一个用于将数据捕获到 MemoryStream 的默认实现,请参阅 https://github.com/cefsharp/CefSharp/wiki/General-Usage#response-filtering 示例 (3认同)
  • 在上面的示例中,“FilterStatus IResponseFilter.Filter()”代码不正确。在 DataIn 大于 DataOut 的情况下,此代码会引发异常。请参阅:**honestabelink**对此[链接](https://github.com/cefsharp/CefSharp/issues/2433)页面的评论 (2认同)