使用CEF類庫處理HTTP請求

來源:互聯網
上載者:User

標籤:tco   自己   實現   clu   markdown   int   原創   XML   標頭檔   

當我們基於CEF開發應用時,可能會有URL請求處理的需求,比方HTTP下載或上傳。此時能夠利用CEF提供的類庫來完畢,而不必自己實現或引入其他第三方的類庫。

在CEF裡為URL Request設計了兩組類,一組用於運行網路請求,一組代表請求資料。

foruok原創。轉載請保留出處或關注foruok的訂閱號“程式視界”來聯絡foruok。

URLRequest

CefURLRequest是運行URL請求的類(介面),相應的標頭檔是cef_urlrequest.h,實現則在libcef/common/urlrequest_impl.cc檔案裡。

CefURLRequest類的靜態方法Create()能夠建立並運行一個URL請求。它的原型例如以下:

static CefRefPtr<CefURLRequest> Create(      CefRefPtr<CefRequest> request,      CefRefPtr<CefURLRequestClient> client,      CefRefPtr<CefRequestContext> request_context);

第一個參數,類型是CefRequest,代表一個URL請求。CEF庫內部已經實現了,後面會講到。

第二個參數。類型是CefURLRequestClient,用於接收server返回的狀態和資料,須要我們自己繼承CefURLRequestClient介面實現一個非抽象類別。

後面有了。

第三個參數。CefRequestContext,為NULL時內部會自己建立一個合適的Context。不為NULL時就用傳入的Context。

Create方法會依據當前是Browser進程還是Renderer進程來建立相應的URLRequest類,CefBrowserURLRequest(browser_urlrequest_impl.h/.cc)或CefRenderURLRequest(render_urlrequest_impl.h/.cc)。

這麼分析下來,我們要進行URL請求,實際上要做的工作就是:

  • 構造一個CefRequest,代表我們的請求
  • 寫一個類實現CefURLRequestClient介面來處理響應。
  • 調用CefURLRequest::Create()建立一個URL請求處理對象
構造Request

CefRequest類代表了一個URL請求。它裡面能夠配置方法、URL、頭部、上傳的資料等。以下的程式碼片段示範了怎樣構造一個 CefRequest 對象:

CefRefPtr<CefPostData> data = CefPostData::Create();CefRefPtr<CefPostDataElement> element = CefPostDataElement::Create();const char szData[] = "Hello World!";element->SetToBytes(sizeof(szData) - 1, (const void*)szData);data->AddElement(element);CefRequest::HeaderMap headers;headers.insert(std::make_pair("Content-Type", "text/plain"));headers.insert(std::make_pair("Accept", "text/plain"));CefRefPtr<CefRequest> req = CefRequest::Create();req->SetMethod("POST");req->SetURL("http://xxx.net");req->SetHeaderMap(headers);req->SetPostData(data);

與一個請求相關的類和介面,都在cef_request.h中,實如今request_impl.cc中。

這些類都有靜態Create方法。能夠返回一個代表詳細執行個體的介面。然後就能夠介面的方法來定製執行個體對象,定製後的對象就能夠用於URL請求了。

剛才的程式碼片段示範了怎樣構造一個CefRequest對象。當中用到了以下的類(介面):

  • CefRequest,代表了一個URL請求
  • CefPostData,管理要通過請求發送的資料。它內部維護了多個CefPostDataElement。每一個CefPostDataElement代表了一個要發送的資料元素
  • CefPostDataElement,代表發送的資料。提供了一些介面。能夠關聯到檔案,也能夠直接發送位元組

想瞭解至於這些類的介面,開啟標頭檔看看吧。

實現CefURLRequestClient介面

CefURLRequestClient介面的實現能夠非常easy。我實現了一個簡單的UrlRequestClient類。

UrlRequestClient.h例如以下:

#ifndef URL_REQUEST_CLIENT_H#define URL_REQUEST_CLIENT_H#include <string>#include "include/cef_urlrequest.h"#include "include/wrapper/cef_helpers.h"class UrlRequestCompletionCallback{public:    virtual ~UrlRequestCompletionCallback(){}    virtual void OnCompletion(CefURLRequest::ErrorCode errorCode,        const std::string& data) = 0;};class UrlRequestClient : public CefURLRequestClient{public:    UrlRequestClient()        : m_callback(0)    {        CEF_REQUIRE_UI_THREAD();    }    UrlRequestClient(UrlRequestCompletionCallback *callback)        : m_callback(callback)     {        CEF_REQUIRE_UI_THREAD();    }    //    //interfaces of CefURLRequestClient    //    void OnRequestComplete(CefRefPtr<CefURLRequest> request) OVERRIDE;    void OnUploadProgress(CefRefPtr<CefURLRequest> request,        int64 current,        int64 total) OVERRIDE;    void OnDownloadProgress(CefRefPtr<CefURLRequest> request,        int64 current,        int64 total) OVERRIDE;    void OnDownloadData(CefRefPtr<CefURLRequest> request,        const void* data,        size_t data_length) OVERRIDE;    bool GetAuthCredentials(bool isProxy,        const CefString& host,        int port,        const CefString& realm,        const CefString& scheme,        CefRefPtr<CefAuthCallback> callback) OVERRIDE{        return false;    }    void Request(CefRefPtr<CefRequest> cef_request);    void Get(const std::string &url, const CefRequest::HeaderMap &headers = CefRequest::HeaderMap());    void Post(const std::string &url, const CefRefPtr<CefPostData> data, const CefRequest::HeaderMap &headers = CefRequest::HeaderMap());    void SetCompletionCallback(UrlRequestCompletionCallback *callback)    {        m_callback = callback;    }private:    UrlRequestCompletionCallback *m_callback;    CefRefPtr<CefURLRequest> m_urlRequest;    std::string m_data;    IMPLEMENT_REFCOUNTING(UrlRequestClient);    DISALLOW_COPY_AND_ASSIGN(UrlRequestClient);};class PrintUrlReqCallback : public UrlRequestCompletionCallback{public:    void OnCompletion(CefURLRequest::ErrorCode errorCode, const std::string& data);};#endif

UrlRequestClient.cpp內容例如以下:

#include "UrlRequestClient.h"#include <Windows.h>void UrlRequestClient::OnRequestComplete(CefRefPtr<CefURLRequest> request){    CEF_REQUIRE_UI_THREAD();    if (m_callback) {        m_callback->OnCompletion(request->GetRequestError(), m_data);    }}void UrlRequestClient::OnUploadProgress(CefRefPtr<CefURLRequest> request, int64 current, int64 total){}void UrlRequestClient::OnDownloadProgress(CefRefPtr<CefURLRequest> request, int64 current, int64 total){    char szLog[128] = { 0 };    sprintf_s(szLog, 128, "UrlRequestClient::OnDownloadProgress, current-%lld, total-%lld\r\n",        current, total);    OutputDebugStringA(szLog);}void UrlRequestClient::OnDownloadData(CefRefPtr<CefURLRequest> request, const void* data, size_t data_length){    m_data += std::string(static_cast<const char*>(data), data_length);}void UrlRequestClient::Request(CefRefPtr<CefRequest> cef_request){    m_urlRequest = CefURLRequest::Create(cef_request, this, NULL);}void UrlRequestClient::Get(const std::string &url, const CefRequest::HeaderMap &headers /*= CefRequest::HeaderMap()*/){    CefRefPtr<CefRequest> req = CefRequest::Create();    req->SetURL(url);    req->SetMethod("GET");    req->SetHeaderMap(headers);    Request(req);}void UrlRequestClient::Post(const std::string &url, const CefRefPtr<CefPostData> data, const CefRequest::HeaderMap &headers /*= CefRequest::HeaderMap()*/){    CefRefPtr<CefRequest> req = CefRequest::Create();    req->SetURL(url);    req->SetMethod("POST");    req->SetHeaderMap(headers);    req->SetPostData(data);    Request(req);}//// for test//void PrintUrlReqCallback::OnCompletion(CefURLRequest::ErrorCode errorCode, const std::string& data){    char szLog[128] = { 0 };    sprintf_s(szLog, 128, "PrintUrlReqCallback::OnCompletion, errorCode = %d, data.len = %d, data:\r\n",         errorCode, data.length());    OutputDebugStringA(szLog);    delete this;}

UrlRequestClient類能夠發起URL請求並處理響應。它的使用方法相似以下這樣(注意要在Browser進程的UI線程使用):

// Get() testUrlRequestClient *client = new UrlRequestClient(new PrintUrlReqCallback);std::string url("http://www.baidu.com");client->Get(url);// Request() testCefRefPtr<CefRequest> req = CefRequest::Create();req->SetMethod("GET");req->SetURL("http://www.csdn.net");CefRequest::HeaderMap headers;headers.insert(std::make_pair("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"));headers.insert(std::make_pair("Accept-Encoding", "gzip,deflate,sdch"));headers.insert(std::make_pair("Accept-Language", "en,zh"));req->SetHeaderMap(headers);(new UrlRequestClient(new PrintUrlReqCallback))->Request(req);// Post() testCefRefPtr<CefPostData> data = CefPostData::Create();CefRefPtr<CefPostDataElement> element = CefPostDataElement::Create();const char szData[] = "Hello World!";element->SetToBytes(sizeof(szData) - 1, (const void*)szData);data->AddElement(element);CefRequest::HeaderMap headers;headers.insert(std::make_pair("Content-Type", "text/plain"));headers.insert(std::make_pair("Accept", "text/plain"));(new UrlRequestClient(new PrintUrlReqCallback))->Post("http://xxx.com/hello", data, headers);

就這樣吧。

關於CEF裡的線程,能夠參考:http://blog.csdn.net/foruok/article/details/50674141。

關於進程,能夠參考:http://blog.csdn.net/foruok/article/details/50621751。

其他參考文章詳見我的專欄:【CEF與PPAPI開發】。

使用CEF類庫處理HTTP請求

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.