1. 程式人生 > >使用CEF類庫處理HTTP請求

使用CEF類庫處理HTTP請求

                     

當我們基於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);
  • 1
  • 2
  • 3
  • 4

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

第二個引數,型別是CefURLRequestClient,用於接收伺服器返回的狀態和資料,需要我們自己繼承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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

與一個請求相關的類和介面,都在cef_request.h中,實現在request_impl.cc中。這些類都有靜態的Create方法,可以返回一個代表具體例項的介面,然後就可以介面的方法來定製例項物件,定製後的物件就可以用於URL請求了。

剛才的程式碼片段演示瞭如何構造一個CefRequest物件,其中用到了下面的類(介面):

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

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

實現CefURLRequestClient介面

CefURLRequestClient介面的實現可以很簡單,我實現了一個簡單的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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80

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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

就這樣吧。

           

相關推薦

使用CEF處理HTTP請求

                     當我們基於CEF開發應用時,可能會有URL請求處理的需求,比如HTTP下載或上傳,此時可以利用CEF提供的類庫來完成,而不必自己實現或引入其它第三方的類庫。在CEF裡為URL Request設計了兩組類,一組用於執行網路請求,一組代表請求資料。  foruok原創,轉

Serlvet 處理http請求並保持長連接

數據 http print htm boa out eth 3.0 cte 一.Servlet,一個請求在容器中是如何處理的 Servlet規定的,相應客戶請求訪問特定Servlet流程如下: 1.客戶端發出請求。 2.Servlet容器接收客戶請求解析。 3.Se

(轉)關於Tomcat的點點滴滴(體系架構、處理http請求的過程、安裝和配置、目錄結構、設置壓縮和對中文文件名的支持、以及Catalina這個名字的由來……等)

https 設置 重啟 specific 調用 持久化數據 所在 original apps 轉自:http://itfish.net/article/41668.html 總結Tomcat的體系架構、處理http請求的過程、安裝和配置、目錄結構、設置壓縮和對中文文件名

java處理HTTP請求

connect implement turn set readline catch append 內容 nco 1 import com.diyfintech.wx.service.HttpService; 2 import org.springframework.s

Spring MVC 處理HTTP請求的整體流程

含義 alt myba 解析 patch ros ati 框架 ice   DispatcherServlet是一個前端控制器,是整個Spring MVC框架的核心組件。它在接收HTTP請求之後,根據請求調用Spring MVC中的各個組件。   常用接口及其含義:   1

Servlet初始化及處理HTTP請求

png cal 共享 servlet配置 用戶訪問 input 端口號 doget 本地 上一篇詳細介紹了與Servlet相關的幾個核心的接口和類,當我們自己寫Servlet類時,一般需要繼承HttpServlet類,實現init()、doGet()、doP

9.5 處理http 請求

default OS ane spa UNC () div min package package main import ( "fmt" "net/http" ) func main() { mux := http.NewServeMux()

Django處理http請求流程圖

技術 line alt 流程圖 AD add IT django tle Django處理http請求流程圖

C# 後臺處理http請求

處理 IT 方式 span 亂碼 bottom AD bytearray ret using System.Collections.Generic;using System.Linq;using System.Text;using System.Net;using Syst

使用Redis處理一般的搶購(秒殺)活動示例

1、建立搶購活動Redis類庫檔案 <?php /** * Created by PhpStorm. */ namespace app\base\service; use mikkle\tp_redis\RedisHashInfoBase; use think\Exception;

linux下使用libcurl開發http請求客戶端

一、運用開源庫libcurl開發http請求客戶端,實現檔案上傳和字串傳送的功能 /****************************************************** *** Copyright(C) *** author Lu GuoFu *** date 2018-

django 是如何處理 http 請求

Web 應用的互動過程其實就是 http 請求與響應的過程。無論是在 PC 端還是移動端,我們通常使用瀏覽器來上網,我們的上網流程大致來說是這樣的: 我們開啟瀏覽器,在位址列輸入我們想訪問的網址,比如 http://www.djangoproject.com/(當然你也可能從收藏夾裡直接

axios處理http請求,對比ajax

在處理http請求方面,已經不推薦使用vue-resource了,而是使用最新的axios,下面做一個簡單的介紹。 安裝 使用node npm install axios 使用cdn <script src="https://unpkg.com/

Spring Boot:AOP統一處理HTTP請求

版權宣告:博主原創/資料整理,轉載請註明出處!! 首先,AOP (Aspect Oriented Programming )指面向切面程式設計,通過預編譯方式或者執行時刻對目標物件動態地新增功能。 一、Spring Boot中新增AOP依賴 <

處理http請求返回的json串

       "application/json;charset=UTF-8");    org.apache.http.client.ResponseHandler handler = new BasicResponseHandler();     String rsp = (String) httpcli

SpringMVC中servlet處理http請求原始碼解析

    Spring MVC的核心控制器為Servlet,所有訪問服務端的請求都將由servlet攔截接受,並進行相應處理最終進行返回。下面我們來看看它究竟是怎麼做的。     SpringMVC中的Servl

Servlet-處理HTTP請求與響應

HttpServletRequest HttpServletRequest 物件代表客戶端的請求,客戶端的所有訊息都封裝在這個物件中,通過這個方法可以獲取請求資料 作用: 讀取和寫入HTTP請求資料 取得和設定Cookies 取得路徑資訊 標識HTTP資

SpringBoot進階之AOP統一處理http請求日誌

相關注解 1、@Aspect  放在類上面,把該類作為一個切面 2、@Pointcut  放在方法上面,定義一個可被別的方法引用的切入點表示式 3、@Before  放在方法上面,前置通知   方法執行前執行 4、@After   放在方法上面     後置最終通知    

Servlet生命週期和處理Http請求與響應

servlet的生命週期:    1.容器開啟並載入servlet;    2.呼叫init()方法對servlet進行初始化;    3.當請求到來呼叫service()方法處理請求,傳送響應;    4.呼叫destory()方法銷燬servlet; servlet處理Http響應        

IIS進行處理HTTP請求的方法

在IIS中要怎麼處理HTTP請求?下面就來看看流程吧。 一、下面的列表描述了請求處理流程: 1、當客戶端發起你個面向伺服器的http請求後,HTTP.sys截獲該請求。 2、HTTP.sys通知WAS從配置檔案中獲取必要的資訊。FTP 3、WAS從applicationHos