Chromium 自定义缓存策略
Chromium Embedded Framework (CEF) 是一个开源库,用于在应用程序中嵌入 Chromium web 浏览器控制。CEF 本身并没有直接提供自定义缓存策略的接口。它主要遵循 Chromium 的缓存策略。
然而,你可以通过一些方式间接地实现自定义缓存策略:
- 自定义请求处理:你可以通过实现 CefRequestHandler 接口来自定义请求的处理。例如,你可以在 OnBeforeResourceLoad 方法中修改请求的头部,添加或修改 Cache-Control 头部来控制缓存行为。
- 禁用缓存:如果你想完全禁用缓存,你可以在创建 CefBrowser 或 CefRequest 时设置 cache_path 为空。
- 离线缓存:CEF 支持 HTML5 的应用程序缓存(AppCache),你可以使用它来实现离线缓存。
- 自定义协议:你可以通过实现 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将使用默认的网络堆栈来处理请求。
本文来自博客园,作者:严_青,转载请注明原文链接:https://www.cnblogs.com/zhao-jie-li/p/18120769