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<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,CefRefPtr<CefResponse> response,URLRequestStatus status,int64 received_content_length) {}結果空歡喜一場。我們可以通過request和response指針能 拿到請求頭和請求體 和 響應頭 響應狀態碼等 但就是得不到 響應體!
所以 百度不行,當然谷歌了呀。雖然沒有得到具體代碼提示,但是提示說在 示例程序中有,恍然大悟了 應該回歸初心 ,有什么需求或者問題 都可以看cef示例工程。在cefclient有攔截request請求和響應的例子!
代碼
筆者需求當然實現了,由于是項目代碼 這里不便展示。就把cefclient 中怎么處理的給大家說說。
這里直接說答案,要想獲取 http response的響應體,應該在這個回調函數里面做處理。下面處理是在cefclient示例工程的test_runner.cc文件中的這個函數。
CefRefPtr<CefResponseFilter> ClientHandler::GetResourceResponseFilter(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,CefRefPtr<CefResponse> response) {CEF_REQUIRE_IO_THREAD();return test_runner::GetResourceResponseFilter(browser, frame, request,response); }大家繼續跟代碼,跟蹤到response_filter_test.cc文件下的下面這函數。
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,CefRefPtr<CefResponse> 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请求和响应也能拦截到)的全部內容,希望文章能夠幫你解決所遇到的問題。