CEF 网络层

默认情况下,CEF3中的网络请求将以对主机应用程序透明的方式处理。对于希望与网络层建立更密切关系的应用,CEF3暴露了一系列与网络相关的功能。

网络相关的回调可能发生在不同的线程上,因此请务必注意文档并正确保护您的数据成员。

自定义请求

在浏览器框架中加载URL的最简单方法是通过CefFrame :: LoadURL()方法。

browser->GetMainFrame()->LoadURL(some_url);

希望发送包含自定义请求标头或上传数据的更复杂请求的应用程序可以使用CefFrame :: LoadRequest()方法。此方法接受CefRequest对象作为单个参数。

// Create a CefRequest object.
CefRefPtr<CefRequest> request = CefRequest::Create();

// Set the request URL.
request->SetURL(some_url);

// Set the request method. Supported methods include GET, POST, HEAD, DELETE and PUT.
request->SetMethod(“POST”);

// Optionally specify custom headers.
CefRequest::HeaderMap headerMap;
headerMap.insert(
    std::make_pair("X-My-Header", "My Header Value"));
request->SetHeaderMap(headerMap);

// Optionally specify upload content.
// The default “Content-Type” header value is "application/x-www-form-urlencoded".
// Set “Content-Type” via the HeaderMap if a different value is desired.
const std::string& upload_data = “arg1=val1&arg2=val2”;
CefRefPtr<CefPostData> postData = CefPostData::Create();
CefRefPtr<CefPostDataElement> element = CefPostDataElement::Create();
element->SetToBytes(upload_data.size(), upload_data.c_str());
postData->AddElement(element);
request->SetPostData(postData);

与浏览器无关的请求

应用程序可以通过CefURLRequest类发送与特定浏览器无关的网络请求。实现CefURLRequestClient接口以处理生成的响应。CefURLRequest可以在浏览器和渲染过程中使用。

class MyRequestClient : public CefURLRequestClient {
 public:
  MyRequestClient()
    : upload_total_(0),
      download_total_(0) {}

  void OnRequestComplete(CefRefPtr<CefURLRequest> request) OVERRIDE {
    CefURLRequest::Status status = request->GetRequestStatus();
    CefURLRequest::ErrorCode error_code = request->GetRequestError();
    CefRefPtr<CefResponse> response = request->GetResponse();

    // Do something with the response...
  }

  void OnUploadProgress(CefRefPtr<CefURLRequest> request,
                        int64 current,
                        int64 total) OVERRIDE {
    upload_total_ = total;
  }

  void OnDownloadProgress(CefRefPtr<CefURLRequest> request,
                          int64 current,
                          int64 total) OVERRIDE {
    download_total_ = total;
  }

  void OnDownloadData(CefRefPtr<CefURLRequest> request,
                      const void* data,
                      size_t data_length) OVERRIDE {
    download_data_ += std::string(static_cast<const char*>(data), data_length);
  }

  bool GetAuthCredentials(bool isProxy,
                          const CefString& host,
                          int port,
                          const CefString& realm,
                          const CefString& scheme,
                          CefRefPtr<CefAuthCallback> callback) OVERRIDE {
    return false;  // Not handled.
  }

 private:
  int64 upload_total_;
  int64 download_total_;
  std::string download_data_;

 private:
  IMPLEMENT_REFCOUNTING(MyRequestClient);
};

发送请求:

// Set up the CefRequest object.
CefRefPtr<CefRequest> request = CefRequest::Create();
// Populate |request| as shown above...

// Create the client instance.
CefRefPtr<MyRequestClient> client = new MyRequestClient();

// Start the request. MyRequestClient callbacks will be executed asynchronously.
CefRefPtr<CefURLRequest> url_request = CefURLRequest::Create(request, client.get(), nullptr);
// To cancel the request: url_request->Cancel();

使用CefURLRequest进行的请求还可以通过CefRequest :: SetFlags()方法指定自定义行为。支持的位标志包括:

  • UR_FLAG_SKIP_CACHE如果设置,则在处理请求时将跳过缓存。
  • UR_FLAG_ALLOW_CACHED_CREDENTIALS如果设置的cookie可以随请求一起发送并从响应中保存。还必须设置UR_FLAG_ALLOW_CACHED_CREDENTIALS。
  • UR_FLAG_REPORT_UPLOAD_PROGRESS如果设置上传进度事件将在请求具有正文时生成。
  • UR_FLAG_NO_DOWNLOAD_DATA如果设置,则不会调用CefURLRequestClient :: OnDownloadData方法。
  • UR_FLAG_NO_RETRY_ON_5XX如果设置5XX重定向错误将传播给观察者而不是自动重新尝试。这当前仅适用于源自浏览器进程的请求。
    例如,要跳过缓存而不报告下载数据:
    request->SetFlags(UR_FLAG_SKIP_CACHE | UR_FLAG_NO_DOWNLOAD_DATA);
    

    请求处理

    CEF3支持两种处理应用程序内部网络请求的方法。方案处理程序方法允许为针对特定来源(方案+域)的请求注册处理程序。请求拦截方法允许应用程序自行决定处理任意请求。

使用HTTP方案而不是自定义方案来避免一系列潜在问题。

如果您选择使用自定义方案(什么比“HTTP”等,“HTTPS”等),你必须用CEF注册它,这样它会像预期的那样。如果您想您的自定义方案的行为类似于HTTP(支持POST请求和执行HTTP访问控制(CORS)的限制),那么它应该被注册为“标准”方案。如果您计划对其他方案执行跨源请求或通过XMLHttpRequest将POST请求发送到您的方案处理程序,那么您应该使用HTTP方案而不是自定义方案来避免潜在问题。如果您希望使用自定义方案,则通过CefApp :: OnRegisterCustomSchemes()回调注册属性,该回调必须在所有进程中实现。

void MyApp::OnRegisterCustomSchemes(CefRefPtr<CefSchemeRegistrar> registrar) {
  // Register "client" as a standard scheme.
  registrar->AddCustomScheme("client", true, ...);
}

通用资源管理器

CEF提供了用于管理来自一个或多个数据源的资源请求的通用实现。此用户注册不同数据源的处理程序,例如磁盘上的目录,zip存档或自定义实现,并且管理器处理请求。一个应用程序通过将其从标准的CEF C ++回调(OnBeforeResourceLoad,GetResourceHandler)数据与路由器交互。有关演示CefResourceManager用法的独立示例应用程序,请参阅resource_manager示例。有关完整的使用文档,请参阅include / wrapper / cef_resource_manager.h。

方案处理程序

方案处理程序通过CefRegisterSchemeHandlerFactory()函数注册。调用此函数的好地方是CefBrowserProcessHandler :: OnContextInitialized()。例如,您可以为“client:// myapp /”请求注册处理程序:

CefRegisterSchemeHandlerFactory("client", “myapp”, new MySchemeHandlerFactory());

处理程序可以与内置方案(HTTP,HTTPS等)和自定义方案一起使用。使用内置方案时,请选择应用程序特有的域名(例如“myapp”或“internal”)。实现CefSchemeHandlerFactory和CefResourceHandler类来处理请求并提供响应数据。如果使用自定义方案,请不要忘记实现如上所述的CefApp :: OnRegisterCustomSchemes方法。有关演示CefSchemeHandlerFactory用法的独立示例应用程序,请参阅scheme_handler示例。有关完整的使用文档,请参阅include / cef_scheme.h。

如果响应数据在请求时是已知的,则CefStreamResourceHandler类提供了CefResourceHandler的方便的默认实现。

// CefStreamResourceHandler is part of the libcef_dll_wrapper project.
#include “include/wrapper/cef_stream_resource_handler.h”

const std::string& html_content = “<html><body>Hello!</body></html>”;

// Create a stream reader for |html_content|.
CefRefPtr<CefStreamReader> stream =
    CefStreamReader::CreateForData(
        static_cast<void*>(const_cast<char*>(html_content.c_str())),
        html_content.size());

// Constructor for HTTP status code 200 and no custom response headers.
// There’s also a version of the constructor for custom status code and response headers.
return new CefStreamResourceHandler("text/html", stream)

请求拦截

CefRequestHandler :: GetResourceHandler()方法支持拦截任意请求。它使用相同的CefResourceHandler类作为方案处理程序方法。如果使用自定义方案,请不要忘记实现如上所述的CefApp :: OnRegisterCustomSchemes方法。

CefRefPtr<CefResourceHandler> MyHandler::GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) {
  // Evaluate |request| to determine proper handling...
  if (...)
    return new MyResourceHandler();

  // Return NULL for default handling of the request.
  return NULL;
}

响应过滤

CefRequestHandler :: GetResourceResponseFilter()方法支持过滤请求响应数据。有关工作示例,请参阅cefclient / browser / response_filter_test.cc(可通过测试菜单>其他测试>来自cefclient示例应用程序内部的响应过滤)。

其他回调

该CefRequestHandler接口提供了各种网络相关的事件incuding验证,cookie处理,外部协议处理,证书错误等回调。

代理解决方案

使用与Google Chrome相同的命令行标志在CEF3中配置代理设置。

--proxy-server=host:port
      Specify the HTTP/SOCKS4/SOCKS5 proxy server to use for requests. An individual proxy
      server is specified using the format:

        [<proxy-scheme>://]<proxy-host>[:<proxy-port>]

      Where <proxy-scheme> is the protocol of the proxy server, and is one of:

        "http", "socks", "socks4", "socks5".

      If the <proxy-scheme> is omitted, it defaults to "http". Also note that "socks" is equivalent to
      "socks5".

      Examples:

        --proxy-server="foopy:99"
            Use the HTTP proxy "foopy:99" to load all URLs.

        --proxy-server="socks://foobar:1080"
            Use the SOCKS v5 proxy "foobar:1080" to load all URLs.

        --proxy-server="sock4://foobar:1080"
            Use the SOCKS v4 proxy "foobar:1080" to load all URLs.

        --proxy-server="socks5://foobar:66"
            Use the SOCKS v5 proxy "foobar:66" to load all URLs.

      It is also possible to specify a separate proxy server for different URL types, by prefixing
      the proxy server specifier with a URL specifier:

      Example:

        --proxy-server="https=proxy1:80;http=socks4://baz:1080"
            Load https://* URLs using the HTTP proxy "proxy1:80". And load http://*
            URLs using the SOCKS v4 proxy "baz:1080".

--no-proxy-server
      Disables the proxy server.

--proxy-auto-detect
      Autodetect  proxy  configuration.

--proxy-pac-url=URL
      Specify proxy autoconfiguration URL.

如果代理需要身份验证,则将使用| isProxy |执行CefRequestHandler :: GetAuthCredentials()回调。值为true以检索用户名和密码。

bool MyHandler::GetAuthCredentials(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    bool isProxy,
    const CefString& host,
    int port,
    const CefString& realm,
    const CefString& scheme,
    CefRefPtr<CefAuthCallback> callback) {
  if (isProxy) {
    // Provide credentials for the proxy server connection.
    callback->Continue("myuser", "mypass");
    return true;
  }
  return false;
}

应用程序启动期间的Web内容加载可能会因网络代理解析而延迟(例如,如果在Windows上选中“自动检测代理设置”)。为了获得最佳用户体验,请考虑将应用程序设计为首先显示静态启动页面,然后使用元刷新重定向到实际网站- 重定向将被阻止,直到代理解析完成。出于测试目的,可以使用“—no-proxy-server”命令行标志禁用代理解析。通过从命令行运行“chrome —url = …”,也可以在Google Chrome中复制代理解析延迟。

取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

Powered by bytekits.com,汇天下文字,成非凡梦想!!!