CEF3中如何截获XMLHttpRequest(XHR)的笔记

17 篇文章 1 订阅

标题:CEF3中如何截获XMLHttpRequest(HDR)请求和返回数据!

Title:  How to intercept XMLHttpRequest in CEF3!

阅读对象:主要是给自己看的,免得以后忘记。

环境:[1]VS2013SP3  [2]cef_binary_3.1916.1804_windows32

第一次更新日期:2014-11-4

最近更新日期:2014-11-4

正文:

总共分为四步步骤:

第一步:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. extern UINT WM_XMLHttpRequest;  
  2. CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(CefRefPtr<CefBrowser> browser,   
  3.     CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request)  
  4. {  
  5.     //http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10794  
  6.     if (request->GetResourceType() == RT_XHR)  
  7.     {  
  8.         //Second?  
  9.         CefRefPtr<KagulaResourceHandler> resHandler = new KagulaResourceHandler();  
  10.         resHandler->_browser = browser;  
  11.         resHandler->_frame = frame;  
  12.         resHandler->_clientHandler = this;  
  13.   
  14.         return  resHandler;  
  15.     }  
  16.     return NULL;  
  17. }  

第二步:

KagulaResourceHandler.h清单

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #pragma once  
  2. #include <include/cef_app.h>  
  3. #include <include/cef_urlrequest.h>  
  4. class ClientHandler;  
  5. class KagulaUrlRequestClient;  
  6. class KagulaResourceHandler : public CefResourceHandler  
  7. {  
  8. public:  
  9.     KagulaResourceHandler() :  
  10.         _offset(0)  
  11.     {}  
  12.   
  13.     virtual bool   ProcessRequest(CefRefPtr<CefRequest> request,  
  14.         CefRefPtr<CefCallback> callback)  
  15.         OVERRIDE;  
  16.     virtual void   GetResponseHeaders(CefRefPtr<CefResponse> response,  
  17.         int64& response_length,  
  18.         CefString& redirectUrl) OVERRIDE;  
  19.     virtual void   Cancel() OVERRIDE;  
  20.   
  21.     virtual bool   ReadResponse(void* data_out, int bytes_to_read,  
  22.         int& bytes_read,  
  23.         CefRefPtr<CefCallback> callback)  
  24.         OVERRIDE;  
  25.   
  26. public:  
  27.     CefRefPtr<ClientHandler> _clientHandler;  
  28.     CefRefPtr<CefBrowser> _browser;  
  29.     CefRefPtr<CefFrame> _frame;  
  30.   
  31.     CefRefPtr<CefCallback> _responseHeadersReadyCallback;  
  32.   
  33.     CefRefPtr<KagulaUrlRequestClient> _webRequestClient;  
  34.     CefRefPtr<CefURLRequest> _webRequest;  
  35.   
  36.     std::string _content;  
  37. private:  
  38.     size_t _offset;  
  39.   
  40.     IMPLEMENT_REFCOUNTING(KagulaResourceHandler);  
  41.     IMPLEMENT_LOCKING(KagulaResourceHandler);  
  42. };  


KagulaResourceHandler.cpp清单

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <assert.h>  
  2.   
  3. #include "KagulaResourceHandler.h"  
  4. #include "client_handler.h"  
  5. #include "KagulaUrlRequestClient.h"  
  6.   
  7. bool KagulaResourceHandler::ProcessRequest(CefRefPtr<CefRequest> request,  
  8.     CefRefPtr<CefCallback> callback)  
  9. {  
  10.     //1. Start the request using WebRequest  
  11.     //2. Return True to handle the request  
  12.     //3. Once response headers are ready call  
  13.     //   callback.Continue()  
  14.     _responseHeadersReadyCallback = callback;  
  15.   
  16.     _webRequestClient = new KagulaUrlRequestClient(_frame);  
  17.     _webRequestClient->_resourceHandler = this;  
  18.     request->SetFlags(UR_FLAG_ALLOW_CACHED_CREDENTIALS | UR_FLAG_ALLOW_COOKIES);  
  19.   
  20.     //To skip cache :  
  21.     //| request.SetFlags(cefpython.Request.Flags["SkipCache"])  
  22.     //Must keep a strong reference to the WebRequest() object.  
  23.     _webRequest = CefURLRequest::Create(request, _webRequestClient.get());  
  24.   
  25.     return true;  
  26. }  
  27.   
  28. void KagulaResourceHandler::GetResponseHeaders(CefRefPtr<CefResponse> response,  
  29.     int64& response_length, CefString& redirectUrl)  
  30. {  
  31.     assert(CefCurrentlyOn(TID_IO));  
  32.     //if (this->mimeType)  
  33.     //{  
  34.     //  response->SetMimeType(CefString(this->mimeType));  
  35.     //  response->SetStatus(200);  
  36.     //}  
  37.     //else  
  38.     //{  
  39.     //  response->SetStatus(500);  
  40.     //}  
  41.     CefRefPtr<CefResponse> webResponse = _webRequestClient->_response;  
  42.   
  43.     if (webResponse!=nullptr)  
  44.     {  
  45.         CefResponse::HeaderMap headerMap;  
  46.         webResponse->GetHeaderMap(headerMap);  
  47.         response->SetHeaderMap(headerMap);  
  48.         response->SetStatus(webResponse->GetStatus());  
  49.         response->SetStatusText(webResponse->GetStatusText());  
  50.         CefString cefstr = webResponse->GetMimeType();  
  51.         if (!cefstr.empty())  
  52.         {  
  53.             response->SetMimeType(webResponse->GetMimeType());  
  54.         }  
  55.     }  
  56.   
  57.     response_length = _content.size();  
  58.     _offset = 0;  
  59. }  
  60.   
  61. void KagulaResourceHandler::Cancel()  
  62. {  
  63. }  
  64.   
  65. bool KagulaResourceHandler::ReadResponse(void* data_out, int bytes_to_read,  
  66.     int& bytes_read, CefRefPtr<CefCallback> callback)  
  67. {  
  68.     //here fill what response data will be return!  
  69.     size_t size = _content.size();  
  70.   
  71.     if (_offset < size) {  
  72.           
  73.         int transfer_size = min(bytes_to_read, static_cast<int>(size - _offset));  
  74.   
  75.         memcpy(data_out, _content.c_str() + _offset, transfer_size);  
  76.         _offset += transfer_size;  
  77.   
  78.         bytes_read = transfer_size;//output  
  79.   
  80.         char *pDataOut = (char*)data_out;  
  81.         return true;  
  82.     }  
  83.     return false;  
  84. }  




KagulaUrlRequestClient.h清单

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #pragma once  
  2. #include <include/cef_app.h>  
  3. #include <include/cef_urlrequest.h>  
  4.   
  5. #include "KagulaResourceHandler.h"  
  6.   
  7. #include <string>  
  8. #include <map>  
  9.   
  10. class KagulaUrlRequestClient : public CefURLRequestClient  
  11. {  
  12. public:  
  13.     KagulaUrlRequestClient(CefRefPtr<CefFrame> _frame):_dataLength(0)   
  14.     {}  
  15.   
  16.     // CefURLRequestClient methods  
  17.     virtual void OnRequestComplete(CefRefPtr<CefURLRequest> request) OVERRIDE;  
  18.     virtual void OnUploadProgress(CefRefPtr<CefURLRequest> request, uint64 current, uint64 total) OVERRIDE;  
  19.     virtual void OnDownloadData(CefRefPtr<CefURLRequest> request, const void* data, size_t data_length) OVERRIDE;  
  20.     virtual void OnDownloadProgress(CefRefPtr<CefURLRequest> request, uint64 current, uint64 total) OVERRIDE;  
  21.     virtual bool GetAuthCredentials(bool isProxy, const CefString& host, int port, const CefString& realm, const CefString& scheme, CefRefPtr<CefAuthCallback> callback) OVERRIDE;  
  22. public:  
  23.     CefRefPtr<CefResponse> _response;  
  24.     CefRefPtr<KagulaResourceHandler> _resourceHandler;  
  25.   
  26.     std::string _data;  
  27.     size_t _dataLength;  
  28. private:  
  29.     IMPLEMENT_REFCOUNTING(KagulaUrlRequestClient);  
  30. };  


KagulaUrlRequestClient.cpp清单

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "KagulaUrlRequestClient.h"  
  2. #include "client_handler.h"  
  3.   
  4. void KagulaUrlRequestClient::OnRequestComplete(CefRefPtr<CefURLRequest> request)  
  5. {  
  6.     std::string statusText = "Unknown";  
  7.     std::map<int,std::string> mqpReqStatus;  
  8.     mqpReqStatus[0]="Unknown";  
  9.     mqpReqStatus[1]="Success";  
  10.     mqpReqStatus[2]="Pending";  
  11.     mqpReqStatus[3]="Canceled";  
  12.     mqpReqStatus[4]="Failed";  
  13.   
  14.     if (mqpReqStatus.find(request->GetRequestStatus()) != mqpReqStatus.end())  
  15.         statusText = mqpReqStatus[request->GetRequestStatus()];  
  16.   
  17.     _response = request->GetResponse();  
  18.   
  19.         _data = _resourceHandler->_clientHandler->_OnResourceResponse(  
  20.             _resourceHandler->_browser,  
  21.             _resourceHandler->_frame,  
  22.             request->GetRequest(),  
  23.             request->GetRequestStatus(),  
  24.             request->GetRequestError(),  
  25.             request->GetResponse(),  
  26.             _data);  
  27.   
  28.     _dataLength = _data.length();  
  29.   
  30.     //ResourceHandler.GetResponseHeaders() will get called  
  31.     //after _responseHeadersReadyCallback.Continue() is called.  
  32.     _resourceHandler->_content = _data;  
  33.     _resourceHandler->_responseHeadersReadyCallback->Continue();  
  34. }  
  35.   
  36. void KagulaUrlRequestClient::OnUploadProgress(CefRefPtr<CefURLRequest> request, uint64 current, uint64 total)  
  37. {  
  38. }  
  39.   
  40. void KagulaUrlRequestClient::OnDownloadData(CefRefPtr<CefURLRequest> request, const void* data, size_t data_length)  
  41. {  
  42.     char* buf = new char[data_length + 1];  
  43.     if (buf!=nullptr)  
  44.     {  
  45.         memset(buf, 0, data_length + 1);  
  46.         memcpy(buf, data, data_length);  
  47.         _data += buf;  
  48.         delete buf;  
  49.     }  
  50. }  
  51.   
  52. void KagulaUrlRequestClient::OnDownloadProgress(CefRefPtr<CefURLRequest> request, uint64 current, uint64 total)  
  53. {  
  54. }  
  55.   
  56. bool KagulaUrlRequestClient::GetAuthCredentials(bool isProxy, const CefString& host, int port, const CefString& realm, const CefString& scheme, CefRefPtr<CefAuthCallback> callback)  
  57. {  
  58.     return true;  
  59. }  


第三步:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. std::string ClientHandler::_OnResourceResponse(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request,   
  2.     CefURLRequest::Status status, CefURLRequest::ErrorCode errorCode, CefRefPtr<CefResponse> response, std::string data)  
  3. {  
  4.     std::string _data = data;  
  5.     std::string strPostData;  
  6.   
  7.     std::wstring wsR = L"url=>";  
  8.     wsR.append(frame->GetURL().ToWString());  
  9.     wsR.append(L"post data=>");  
  10.     {  
  11.         CefRefPtr<CefPostData> postData = request->GetPostData();  
  12.   
  13.         if (postData != NULL) {  
  14.             CefPostData::ElementVector elements;  
  15.             postData->GetElements(elements);  
  16.   
  17.             if (elements.size() > 0) {  
  18.   
  19.                 std::wstring queryString;  
  20.   
  21.                 // it looks like the whole query string is in this first post data element?  
  22.                 CefRefPtr<CefPostDataElement> query = elements[0];  
  23.   
  24.                 if (query->GetType() == PDE_TYPE_BYTES || query->GetType() == PDE_TYPE_FILE) {  
  25.                     const unsigned int buffSize = query->GetBytesCount() >= 1024 ? 1024 : query->GetBytesCount() + 1;  
  26.                     char *buff = new char[buffSize];  
  27.                     if (buff!=nullptr)  
  28.                     {  
  29.                         //Get Post Data  
  30.                         memset(buff, 0, buffSize);  
  31.                           
  32.                         query->GetBytes(query->GetBytesCount() >= buffSize ? buffSize-1 : query->GetBytesCount(), buff);  
  33.                         strPostData = buff;  
  34.                           
  35.                         wsR.append(kagula::s2ws_FromUTF8(strPostData));  
  36.                         delete[] buff;  
  37.                     }  
  38.                 }  
  39.             }  
  40.         }  
  41.     }  
  42.     wsR.append(L"content=>");  
  43.     wsR.append(kagula::s2ws_FromUTF8(data));  
  44.     LOG_TRACE(wsR.c_str());  
  45.   
  46.     //  
  47.     CefString url = frame->GetURL();  
  48.     //send to my main window!  
  49.     std::vector<std::string> vecStr;  
  50.     vecStr.push_back(url.ToString());  
  51.     vecStr.push_back(strPostData);  
  52.     vecStr.push_back(data);  
  53.     CIPCData::SetVecStr(vecStr);  
  54.     HWND hwnd = (HWND)(CIPCData::GetMainHWND());  
  55.     SendMessage(hwnd, WM_XMLHttpRequest, NULL, NULL);  
  56.   
  57.     return _data;  
  58. }  


第四步:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. LRESULT Ccat8637_BrandDlg::OnXMLHttpRequest(WPARAM wParam, LPARAM lParam)  
  2. {  
  3.     std::vector<std::string> vecS;  
  4.     CIPCData::GetVecStr(vecS);  
  5.     if (vecS.size() == 3)  
  6.     {  
  7. #ifdef _DEBUG  
  8.         std::wstring strMsg = L"OnXMLHttpRequest=>";   
  9.         strMsg.append(kagula::s2ws_FromUTF8(vecS[2]));  
  10.         LOG_TRACE(strMsg);  
  11. #endif  
  12.     }  
  13.   
  14.     return S_OK;  
  15. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值