CEF3:拦截http request请求和response响应(包括ajax请求和响应也能拦截到)

文章目录

  • 前言
  • 思路
  • 代码

前言

笔者在项目开发中有需求,需要拦截 js中 发起的 http 请求和响应数据 写到文件中,方便给开发人员或者测试人员查看。笔者拿到这个需求第一反应是,cef肯定有这种接口可供我们使用,所以肯定能实现咯。这里笔者用的是cef2623版本

思路

笔者百度了一下 大致可以在 CefRequestHandler的回调函数可以得到一些东西,一开始 笔者找到的最相近的方法是 下面这个函数OnResourceLoadComplete,既有request 又有response

  ///
  // 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指针能 拿到请求头和请求体 和 响应头 响应状态码等 但就是得不到 响应体!

所以 百度不行,当然谷歌了呀。虽然没有得到具体代码提示,但是提示说在 示例程序中有,恍然大悟了 应该回归初心 ,有什么需求或者问题 都可以看cef示例工程。在cefclient有拦截request请求和响应的例子!

CEF3:拦截http request请求和response响应(包括ajax请求和响应也能拦截到)_第1张图片
CEF3:拦截http request请求和response响应(包括ajax请求和响应也能拦截到)_第2张图片

代码

笔者需求当然实现了,由于是项目代码 这里不便展示。就把cefclient 中怎么处理的给大家说说。

这里直接说答案,要想获取 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指针获取到。

// 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请求进行的测试。

CEF3:拦截http request请求和response响应(包括ajax请求和响应也能拦截到)_第3张图片
CEF3:拦截http request请求和response响应(包括ajax请求和响应也能拦截到)_第4张图片

你可能感兴趣的:(【L_CEF】,cef3拦截http请求,cef3拦截http响应,cef3拦截http数据,cef3拦截请求和响应,cef2623)