Reputation: 53
Note: I'm using the CefSharp browser for this.
I'm trying to read every JSON response from a XMLHttpRequest.
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;
}
}
I'm unable to read the JSON response because stream is null.
How can I read the JSON response content from a XMLHttpRequest?
Upvotes: 1
Views: 5002
Reputation: 547
I have a solution.
I am using cefsharp 49.
We read it in a filter:
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];
}
}
}
and in class DefaultRequestHandler : IRequestHandler
we implement methods below.
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);
}
The filter.dataAll
is what we need!
We can display the string using something like:
ASCIIEncoding encoding = new ASCIIEncoding();
string data = encoding.GetString(filter.DataAll.ToArray());
Console.WriteLine(data);
finally use it in your form.
var wb = new ChromiumWebBrowser("http://www.bilibili.com/video/av8503878/")
{
Dock = DockStyle.Fill,
RequestHandler = new DefaultRequestHandler()
};
Upvotes: 4