首页 > 其他分享 >Chromium 自定义缓存策略

Chromium 自定义缓存策略

时间:2024-04-08 11:48:55浏览次数:19  
标签:CEF 缓存 自定义 CefRefPtr data request MyRequestHandler Chromium

目录
Chromium Embedded Framework (CEF) 是一个开源库,用于在应用程序中嵌入 Chromium web 浏览器控制。CEF 本身并没有直接提供自定义缓存策略的接口。它主要遵循 Chromium 的缓存策略。
然而,你可以通过一些方式间接地实现自定义缓存策略:

  1. 自定义请求处理:你可以通过实现 CefRequestHandler 接口来自定义请求的处理。例如,你可以在 OnBeforeResourceLoad 方法中修改请求的头部,添加或修改 Cache-Control 头部来控制缓存行为。
  2. 禁用缓存:如果你想完全禁用缓存,你可以在创建 CefBrowser 或 CefRequest 时设置 cache_path 为空。
  3. 离线缓存:CEF 支持 HTML5 的应用程序缓存(AppCache),你可以使用它来实现离线缓存。
  4. 自定义协议:你可以通过实现 CefSchemeHandlerFactory 和 CefResourceHandler 来创建自定义协议,然后在自定义协议中实现你自己的缓存策略。
    请注意,以上方法可能需要对 CEF 和 Chromium 的内部机制有一定的了解,并且可能需要一些编程工作。

CefRequestHandler 在什么位置实现

CefRequestHandler是一个接口,你可以通过创建一个新的类来实现它,这个新类可以在你的项目中的任何位置。以下是一个基本的例子:

class MyRequestHandler : public CefRequestHandler {
public:    MyRequestHandler() {}    
virtual ~MyRequestHandler() {}    
// Implement methods from CefRequestHandler as needed.    
// For example:    
virtual ReturnValue OnBeforeResourceLoad(        
CefRefPtr browser,        
CefRefPtr frame,        
CefRefPtr request,        
CefRefPtr callback) OVERRIDE {        
// Modify request as needed.        
return RV_CONTINUE;   
}
private:    
IMPLEMENT_REFCOUNTING(MyRequestHandler);};

然后你需要在你的CefClient实现中返回这个处理器:

class MyClient : public CefClient {
public:    MyClient() : request_handler_(new MyRequestHandler()) {}   
virtual CefRefPtr GetRequestHandler() OVERRIDE {       
return request_handler_;    
}    
// Implement other methods as needed.
private:    
CefRefPtr request_handler_;    
IMPLEMENT_REFCOUNTING(MyClient);};

这样,CEF 就会在适当的时候调用你的MyRequestHandler实现。

我如何将本地资源作为该请求资源返回呢?

在CEF(Chromium Embedded Framework)中,你可以通过实现自定义的CefResourceHandler来实现这个功能。下面是一个简单的例子:

class MyResourceHandler : public CefResourceHandler {
public:
    MyResourceHandler() {}

    bool ProcessRequest(CefRefPtr<CefRequest> request,
                        CefRefPtr<CefCallback> callback) OVERRIDE {
        // Check the URL of the request and decide whether you want to handle this request.
        if (request->GetURL() == "http://my.custom.url") {
            // Use callback->Continue() to start the request.
            callback->Continue();
            return true;
        }
        return false;
    }

    void GetResponseHeaders(CefRefPtr<CefResponse> response,
                            int64& response_length,
                            CefString& redirectUrl) OVERRIDE {
        // Set up the response headers.
        response->SetMimeType("text/html");
        response->SetStatus(200);

        // Load the resource from local storage.
        std::string html_content = "<html><body>Hello, world!</body></html>";
        data_ = html_content;
        response_length = data_.size();
    }

    bool ReadResponse(void* data_out,
                      int bytes_to_read,
                      int& bytes_read,
                      CefRefPtr<CefCallback> callback) OVERRIDE {
        // Copy the data from your local resource to data_out.
        int size = std::min(bytes_to_read, static_cast<int>(data_.size()));
        memcpy(data_out, data_.c_str(), size);
        bytes_read = size;
        data_ = data_.substr(size);
        return true;
    }

private:
    std::string data_;

    IMPLEMENT_REFCOUNTING(MyResourceHandler);
};

然后在你的CefRequestHandler实现中返回这个资源处理器:

lass MyRequestHandler : public CefRequestHandler {
public:
    MyRequestHandler() {}

    CefRefPtr<CefResourceHandler> GetResourceHandler(
        CefRefPtr<CefBrowser> browser,
        CefRefPtr<CefFrame> frame,
        CefRefPtr<CefRequest> request) OVERRIDE {
        return new MyResourceHandler();
    }

    // Implement other methods as needed.

private:
    IMPLEMENT_REFCOUNTING(MyRequestHandler);
};

这样,当请求的URL匹配你的自定义URL时,CEF会调用你的MyResourceHandler来处理这个请求,并从本地资源中读取数据。

我怎么缓存网络资源呢,比如图片和视频?

CEF(Chromium Embedded Framework)本身已经包含了一个强大的缓存机制,它会自动缓存网络请求的结果(包括图片和视频)。你只需要在创建CefSettings时,设置cache_path属性为你想要的缓存路径即可:

CefSettings settings;
CefString(&settings.cache_path) = "/path/to/cache";

这样CEF就会自动将网络资源缓存在指定的路径下。

如果你想要更细粒度的控制,比如只缓存特定的资源,或者自定义缓存的策略,你可能需要实现自己的CefResourceHandler,在其中处理资源的缓存。这需要对CEF的内部机制有深入的理解,且可能需要大量的代码来实现。

CefResourceHandler 如何实现缓存图片和视频,缓存时间无限长,设置缓存路径?

CEF(Chromium Embedded Framework)并没有直接提供在CefResourceHandler中设置无限长缓存时间和缓存路径的API。缓存是由CEF内部的网络堆栈自动处理的,而CefResourceHandler主要用于处理自定义的资源请求。

如果你想要控制资源的缓存,你可能需要实现自己的缓存机制。这通常涉及到以下步骤:

在CefResourceHandler的ProcessRequest方法中,检查请求的URL,看是否是你想要缓存的资源。

如果是,那么检查你的缓存(你需要自己实现缓存的存储和检索),看是否已经缓存了这个资源。

如果已经缓存了这个资源,那么在GetResponseHeaders和ReadResponse方法中,返回缓存的资源。

如果没有缓存这个资源,那么继续处理请求,将请求的结果保存到你的缓存中。

这个过程需要你自己实现缓存的存储和检索,包括缓存的路径和过期时间。你可以使用任何你喜欢的存储机制,比如文件系统、数据库等。你也需要自己处理缓存的过期,比如在每次检索缓存时,检查缓存的时间,如果超过你设定的过期时间,那么删除这个缓存。

请注意,这是一个复杂的过程,需要对CEF和网络编程有深入的理解。并且,由于CEF的网络堆栈已经提供了强大的缓存机制,所以在大多数情况下,你可能并不需要自己实现这个功能。

demo

下是一个基本的 CefResourceHandler 的实现示例。这只是一个基础模板,并没有实现缓存功能。要实现缓存功能,你需要在适当的位置添加额外的代码来处理缓存的存储和检索。

class MyResourceHandler : public CefResourceHandler {
 public:
  MyResourceHandler() : offset_(0) {}

  bool ProcessRequest(CefRefPtr<CefRequest> request,
                      CefRefPtr<CefCallback> callback) OVERRIDE {
    REQUIRE_IO_THREAD();

    // TODO: 在这里检查请求的URL,看是否是你想要缓存的资源。

    // TODO: 如果是,检查你的缓存,看是否已经缓存了这个资源。

    // TODO: 如果已经缓存了这个资源,调用callback->Continue()然后返回true。

    // TODO: 如果没有缓存这个资源,继续处理请求。

    return false;
  }

  void GetResponseHeaders(CefRefPtr<CefResponse> response,
                          int64& response_length,
                          CefString& redirectUrl) OVERRIDE {
    REQUIRE_IO_THREAD();

    // TODO: 如果是从缓存中获取的资源,设置相应的响应头。

    // TODO: 设置response_length为资源的长度。
  }

  bool ReadResponse(void* data_out,
                    int bytes_to_read,
                    int& bytes_read,
                    CefRefPtr<CefCallback> callback) OVERRIDE {
    REQUIRE_IO_THREAD();

    // TODO: 如果是从缓存中获取的资源,读取资源到data_out,并设置bytes_read。

    return false;
  }

  bool CanGetCookie(const CefCookie& cookie) OVERRIDE {
    REQUIRE_IO_THREAD();

    // Allow all cookies.
    return true;
  }

  bool CanSetCookie(const CefCookie& cookie) OVERRIDE {
    REQUIRE_IO_THREAD();

    // Allow all cookies.
    return true;
  }

  void Cancel() OVERRIDE {
    REQUIRE_IO_THREAD();
  }

 private:
  std::string data_;
  size_t offset_;

  IMPLEMENT_REFCOUNTING(MyResourceHandler);
};

这个示例中,你需要在 ProcessRequest 方法中检查请求的 URL 和你的缓存,然后在 GetResponseHeaders 和 ReadResponse 方法中返回缓存的资源。你还需要在适当的位置处理缓存的存储和过期。

请注意,这个示例只是一个基础模板,实际的实现可能会更复杂。你可能需要处理各种网络错误,以及缓存的并发访问等问题。你还需要确保你的实现符合HTTP的缓存规则,比如考虑到 Cache-Control 和 Expires 等HTTP头。

MyResourceHandler 在哪里设置?

在CEF中,CefResourceHandler 通常在 CefRequestHandler 的 GetResourceHandler 方法中设置。你需要创建一个实现了 CefRequestHandler 的类,并在 GetResourceHandler 方法中返回你的 MyResourceHandler 实例。

以下是一个基本的示例:

class MyRequestHandler : public CefRequestHandler {
 public:
  MyRequestHandler() {}

  CefRefPtr<CefResourceHandler> GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) OVERRIDE {
    REQUIRE_IO_THREAD();

    // TODO: 在这里检查请求的URL,看是否是你想要处理的资源。

    // TODO: 如果是,创建一个MyResourceHandler实例,并返回。

    return NULL;
  }

  IMPLEMENT_REFCOUNTING(MyRequestHandler);
};

然后,你需要在创建 CefBrowser 时设置这个 CefRequestHandler。这通常在 CefBrowserHost::CreateBrowser 或 CefBrowserHost::CreateBrowserSync 调用时完成。例如:

CefWindowInfo window_info;
CefBrowserSettings browser_settings;
CefRefPtr<MyRequestHandler> request_handler = new MyRequestHandler();

// 创建一个新的CefBrowser实例。
CefBrowserHost::CreateBrowser(window_info, request_handler, url, browser_settings, NULL);

在这个示例中,CEF会在处理每个请求时调用 MyRequestHandler::GetResourceHandler 方法。如果这个方法返回一个 CefResourceHandler 实例,那么CEF将使用这个handler来处理请求。否则,CEF将使用默认的网络堆栈来处理请求。

标签:CEF,缓存,自定义,CefRefPtr,data,request,MyRequestHandler,Chromium
From: https://www.cnblogs.com/zhao-jie-li/p/18120769

相关文章

  • 野外监测图传解决方案 l 自定义数据回传最大200倍压缩,天通野外摄像机PS02
    在物联网时代的巨大浪潮中,我们见证了技术的飞速发展和应用的广泛渗透。然而,传统的人工巡检方式在这一进程中显得越来越力不从心,其效率低下和响应迟缓的问题日益凸显。在许多情况下,人工巡检无法实时捕捉到潜在的风险和异常情况,常常是在事故发生后才能察觉,这种滞后性严重制约了......
  • Ascend C 自定义PRelu算子
    本文分享自华为云社区《AscendC自定义PRelu算子》,作者:jackwangcumt。1PRelu算子概述PReLU是ParametricRectifiedLinearUnit的缩写,首次由何凯明团队提出,和LeakyReLU非常类似,是Relu的改进版本,在几乎没有增加额外参数的前提下既可以提升模型的拟合能力,又能减小过拟合风险。......
  • 【知识点】Redis-缓存-缓存击穿
    缓存击穿:缓存中一个热点数据过期或失效时,由于该数据非常受欢迎,会有大量请求直接打到数据库上,导致数据库负载增大、相应变慢甚至瘫痪。解决方式:互斥锁在查询数据库之前首先获取分布式锁,更新redis之后再释放锁,可以保证数据的强一致性。优缺点:优点:强一致性缺点:性能差逻辑......
  • HTTP的强制缓存和协商缓存
    HTTP的强制缓存和协商缓存HTTP的缓存技术强制缓存ExpiresCache-Control协商缓存If-Modified-Since和Last-ModifiedIf-None-Match和ETag优先级可被缓存的请求方法总结HTTP的缓存技术  当我们进行HTTP请求时,需要将请求报文发送给对端,当服务端收到请求后会做出合适......
  • Android11 - 添加自定义服务注意事项
    添加自定义服务注意事项:a:(Android11)快速编译framework.jar./prebuilts/build-tools/linux-x86/bin/ninja-fout/combined-xx.ninjaframework-minus-apexb:在framework/base/core目录下添加文件java和aidl文件后,编译时需要先makeupdate-api去更新current.txt文件,然后才能......
  • csdn博客自定义模块:显示实时天气、日历、随机语录代码
    目录1.样式说明2.效果展示3.代码下载1.样式说明vip会员或者博客专家可以自定义模块代码,比如我博客的样式,有这几部分组成:灯笼祝福(我这里是龙年快乐,可以自定义更改任何字)、滚动欢迎语(我这里是欢迎访问我的博客,可以自定义更改任何欢迎语)github链接、知乎链接、邮箱发......
  • 自定义排序
    问题:按照A列的排序依据进行排序函数公式:=SORTBY(C2:D8,MATCH(C2:C8,A2:A8,))自定义序列排序:设置自定义序列(如需要): 选取A2:A8》文件》选项》自定义序列》导入自定义排序:选取数据》数据》排序》自定义排序……次序设置为自定义序列......
  • Spring Boot数据缓存之Spring缓存抽象 @Cacheable初体验
    在数据缓存之Cache规范JSR107中对Spring的缓存抽象有了一定的了解,下面通过示例实战对其深入探讨。需要注意的是使用Spring缓存抽象时要关注两点:①确定那些方法需要被缓存    ②缓存策略具体案例如下:1、导入依赖Mysql、Mybatis、W......
  • Promise详解与自定义封装
    文章目录概要一、Promise详解1.构造函数1.1语法1.2参数1.3返回值2.属性2.1[[PromiseState]]2.2[[PromiseResult]]3.方法3.1Promise.prototype.then3.1.1语法3.1.2参数3.1.3返回值3.2Promise.prototype.catch3.2.1语法3.2.2参数3.2.3返回值3.3Promis......
  • Avalonia的自定义用户组件
    Avalonia中的自定义用户控件Avalonia是一个跨平台的.NETUI框架,它允许开发者使用C#和XAML来构建丰富的桌面应用程序。自定义用户控件(UserControl)是Avalonia中一种重要的组件,它允许我们将多个控件组合成一个可重用的单元。本文将介绍如何在Avalonia中定义和使用自定义用户控件,并......