前言
笔者在项目开发中有需求,须要拦截 js中 发起的 http 请求和响应数据 写到文件中,方便给开发人员或者测试人员查看。笔者拿到这个需求第一反应是,cef确定有这种接口可供咱们使用,因此确定能实现咯。这里笔者用的是cef2623版本。jquery
思路
笔者百度了一下 大体能够在 CefRequestHandler的回调函数能够获得一些东西,一开始 笔者找到的最相近的方法是 下面这个函数OnResourceLoadComplete,既有request 又有response。c++
///
// Called on the IO thread when a resource load has completed. |request| and
// |response| represent the request and response respectively and cannot be
// modified in this callback. |status| indicates the load completion status.
// |received_content_length| is the number of response bytes actually read.
///
/*--cef()--*/
virtual void OnResourceLoadComplete(CefRefPtr browser,
CefRefPtr frame,
CefRefPtr request,
CefRefPtr response,
URLRequestStatus status,
int64 received_content_length) {}
结果空欢喜一场。咱们能够经过request和response指针能 拿到请求头和请求体 和 响应头 响应状态码等 但就是得不到 响应体!web
因此 百度不行,固然谷歌了呀。虽然没有获得具体代码提示,可是提示说在 示例程序中有,恍然大悟了 应该回归初心 ,有什么需求或者问题 均可以看cef示例工程。在cefclient有拦截request请求和响应的例子!ajax
代码
笔者需求固然实现了,因为是项目代码 这里不便展现。就把cefclient 中怎么处理的给你们说说。svg
这里直接说答案,要想获取 http response的响应体,应该在这个回调函数里面作处理。下面处理是在cefclient示例工程的test_runner.cc文件中的这个函数。函数
CefRefPtr ClientHandler::GetResourceResponseFilter(
CefRefPtr browser,
CefRefPtr frame,
CefRefPtr request,
CefRefPtr response) {
CEF_REQUIRE_IO_THREAD();
return test_runner::GetResourceResponseFilter(browser, frame, request,
response);
}
你们继续跟代码,跟踪到response_filter_test.cc文件下的下面这函数。测试
CefRefPtr GetResourceResponseFilter(
CefRefPtr browser,
CefRefPtr frame,
CefRefPtr request,
CefRefPtr response) {
// Use the find/replace filter on the test URL.
const std::string& url = request->GetURL();
//if (url.find(kTestUrl) == 0)
// return new FindReplaceResponseFilter();
//if (url.find(kTestUrl) == 0)
// return new PassThruResponseFilter();
//if (MatchesFilterURL(url))
// return new PassThruResponseFilter();
int index2 = url.find("LCX");
if ( index2 >= 0 )
return new PassThruResponseFilter();
return NULL;
}
笔者这里拦截的是url中带有LCX字母的http请求数据。这里最重要的就是下面这个类了。在Filter函数里面data_out参数里面就是 响应体的内容,若是响应体的数据很是大,Filter函数可能会被调用屡次。请求头和请求体和响应头能够经过前面的request response指针获取到。this
// Filter that writes out all of the contents unchanged.
class PassThruResponseFilter : public CefResponseFilter {
public:
PassThruResponseFilter() {}
bool InitFilter() OVERRIDE {
return true;
}
FilterStatus Filter(void* data_in,
size_t data_in_size,
size_t& data_in_read,
void* data_out,
size_t data_out_size,
size_t& data_out_written) OVERRIDE {
DCHECK((data_in_size == 0U && !data_in) || (data_in_size > 0U && data_in));
DCHECK_EQ(data_in_read, 0U);
DCHECK(data_out);
DCHECK_GT(data_out_size, 0U);
DCHECK_EQ(data_out_written, 0U);
// All data will be read.
data_in_read = data_in_size;
// Write out the contents unchanged.
data_out_written = std::min(data_in_read, data_out_size);
if (data_out_written > 0)
memcpy(data_out, data_in, data_out_written);
return RESPONSE_FILTER_DONE;
}
private:
IMPLEMENT_REFCOUNTING(PassThruResponseFilter);
};
下面用ajax发一个 http请求 咱们本身打个断点测试一把。这里笔者 用一个带jquery的页面,在控制台发起一个get请求进行的测试。url