【问题标题】:How to read the JSON response content from a XMLHttpRequest?如何从 XMLHttpRequest 中读取 JSON 响应内容?
【发布时间】:2018-08-11 20:41:49
【问题描述】:

注意:我为此使用CefSharp 浏览器。

目标

我正在尝试从 XMLHttpRequest 读取每个 JSON 响应。

我尝试过的

public class RequestHandler : IRequestHandler
{
    public void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request,
        IResponse response, UrlRequestStatus status, long receivedContentLength)
    {
        if (request.Headers["X-Requested-With"] == "XMLHttpRequest" &&
            response.ResponseHeaders["Content-Type"] == "application/json")
        {
            var resourceHandler = new ResourceHandler();
            long responseLength;
            string redirectUrl;
            var stream = resourceHandler.GetResponse(response, out responseLength, out redirectUrl);
            using (var streamReader = new StreamReader(stream))
            {
                var responseContent = streamReader.ReadToEnd();
                Console.WriteLine(responseContent);
            }
        }
    }

    public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame,
        IRequest request, IResponse response)
    {
        return null;
    }

    public bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request,
        bool isRedirect)
    {
        return false;
    }

    public bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl,
        WindowOpenDisposition targetDisposition, bool userGesture)
    {
        return false;
    }

    public bool OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode,
        string requestUrl,
        ISslInfo sslInfo, IRequestCallback callback)
    {
        return false;
    }

    public void OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath)
    {
    }

    public CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame,
        IRequest request,
        IRequestCallback callback)
    {
        return CefReturnValue.Continue;
    }

    public bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy,
        string host, int port,
        string realm, string scheme, IAuthCallback callback)
    {
        return false;
    }

    public void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status)
    {
    }

    public bool OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize,
        IRequestCallback callback)
    {
        return false;
    }

    public void OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request,
        ref string newUrl)
    {
    }

    public bool OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url)
    {
        return false;
    }

    public void OnRenderViewReady(IWebBrowser browserControl, IBrowser browser)
    {
    }

    public bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request,
        IResponse response)
    {
        return false;
    }
}

问题

我无法读取 JSON 响应,因为 stream 为空。

问题

如何从 XMLHttpRequest 读取 JSON 响应内容?

我在这方面非常缺乏经验。所以,如果我遗漏了任何有用的信息:请告诉我,我会提供。

【问题讨论】:

    标签: c# winforms xmlhttprequest cefsharp


    【解决方案1】:

    我有一个解决方案。
    我正在使用 cefsharp 49

    我们在过滤器中读取它:

    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];
            }
        }
    }
    

    DefaultRequestHandler : IRequestHandler 类中,我们实现了以下方法。

    public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame,
        IRequest request, IResponse response)
    {
        /*if (request.Headers["X-Requested-With"] != "XMLHttpRequest" ||
            response.ResponseHeaders["Content-Type"].Contains("application/json")) return null;*/
    
        if (!response.ResponseHeaders["Content-Type"].Contains("application/json"))
        {
            return null;
        }
    
        var filter = FilterManager.CreateFilter(request.Identifier.ToString());
    
        return filter;
    }
    
    public void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request,
        IResponse response, UrlRequestStatus status, long receivedContentLength)
    {
        if (!response.ResponseHeaders["Content-Type"].Contains("application/json"))
        {
            return;
        }
    
        var filter = FilterManager.GetFileter(request.Identifier.ToString()) as TestJsonFilter;
    
        if (filter != null)
            Console.WriteLine(filter.DataAll);
    }
    

    filter.dataAll 是我们需要的! 我们可以使用类似的方式显示字符串:

    ASCIIEncoding encoding = new ASCIIEncoding();
    string data = encoding.GetString(filter.DataAll.ToArray());
    Console.WriteLine(data);
    

    最终在您的表单中使用它。

    var wb = new ChromiumWebBrowser("http://www.bilibili.com/video/av8503878/")
             {
                Dock = DockStyle.Fill,
                RequestHandler = new DefaultRequestHandler()
             };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-15
      • 1970-01-01
      • 2019-03-19
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 2012-11-30
      相关资源
      最近更新 更多