在Cef auto build下载cefCEF Automated Builds
我下载的是104,使用cefsimple工程。
例如:前端资源如下
通过http协议把前端资源加载出来。所有的资源都通过http://local.test.cn/xxx加载。
前端资源包括index.html、test.css、test.js
index.html:
<!DOCTYPE html><html>
<head>
<meta charset=utf-8>
<title>测试</title>
<div>加载成功!</div>
<div id="test_id" style="width: 100px;height: 100px;" ></div>
<script type="text/javascript" src="http://local.test.cn/js/test.js"></script>
<link rel="stylesheet" href="http://local.test.cn/css/test.css"></link>
<head>
<script>
window.onload = function (){
console.log("load..")
}
</script>
test.css:
简单做个设置背景颜色
#test_id{
background-color: aqua;
}
test.js:
简单终端打印信息
console.log("load test js...")
如果能更改颜色和devtools打印对应信息则表示成功,效果如下:
在cefsimple_win.cc通过CefSettings把远端调试端口打开,就可以在chrome通过localhost:port的方式查看devtools:
我这里设置为1234
在simple_app.cc把加载url地址改为自定义地址:
要处理前端的请求,需要实现接口CefRequestHandler
在接口CefClient有个成员获取该handler
在SimpleHandler继承CefRequestHandler并实现GetRequestHandler:
把SimpleHandler自己返回出去就行
CefRequestHandler是通过GetResourceRequestHandler获得资源请求处理对象的,所以我们override这个成员:
判断url是以http://local.test.cn/开头的就使用自定义的SimpleResourceRequestHandler处理
SimpleResourceRequestHandler是继承接口CefResourceRequestHandler的,里面的成员可以自己看文档,这里只实现GetResourceHandler,GetResourceHandler返回处理资源的对象。在cef中CefResourceHandler都是用来处理资源的,例如还有自定义协议等等。
这里我们返回一个自定义resourceHandler,用来读取我们的本地文件并返回给cef:
CefResourceHandler接口主要实现:
bool Open(CefRefPtr<CefRequest> request,
bool& handle_request,
CefRefPtr<CefCallback> callback)override;
void GetResponseHeaders(CefRefPtr<CefResponse> response,
int64& response_length,
CefString& redirectUrl) override;
bool Read(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefResourceReadCallback> callback) override;
Open接口:
如果url是我们目标的url,则handle_request=true和返回true,告诉cef这个资源立即处理。
GetResponseHeaders
需要告诉Cef响应的资源类型,简单处理文件后缀映射类型:
{"html", "text/html"},
{"css","text/css"},
{"js","text/javascript"}
response_length = -1 是告诉cef这个资源由Read接口控制结束,当Read接口返回false,则cef认为该资源读取完毕。
Read接口
data_out是cef分配好的内存,读取的数据直接拷贝到data_out
SimpleTools主要用来读取文件:
SimpleTools.h
#ifndef CEF_TESTS_CEFSIMPLE_TOOLS_H_
#define CEF_TESTS_CEFSIMPLE_TOOLS_H_
#include <string>
#include <vector>
namespace SimpleTools
{
std::string GetModuleDir();
class LocalFileReader
{
public:
LocalFileReader();
bool PreRead(const std::string& filePath);
size_t Read(void* data_out, int& bytes_to_read);
std::string MimeType();
private:
void formatMimeType(const std::string& filePath);
size_t m_bytesReadPos = 0;
std::vector<char> m_dataBuf;
std::string m_mimeType;
};
}
#endif //CEF_TESTS_CEFSIMPLE_TOOLS_H_
SimpleTools.cc
#include "simple_tools.h"
#include <Windows.h>
#include <cassert>
#include <fstream>
#include <map>
std::string SimpleTools::GetModuleDir()
{
static std::string strDir = []()->std::string {
CHAR path[MAX_PATH];
GetModuleFileNameA(NULL, path, MAX_PATH);
std::string strPath = path;
size_t index = strPath.rfind('\\');
return strPath.substr(0, index);
}();
return strDir;
}
SimpleTools::LocalFileReader::LocalFileReader()
{
}
bool SimpleTools::LocalFileReader::PreRead(const std::string& filePath)
{
m_bytesReadPos = 0;
size_t size = 0;
std::ifstream file;
file.open(filePath, std::ios::binary | std::ios::in);
if (file.is_open())
{
file.seekg(0, file.end);
size = file.tellg();
file.seekg(0);
m_dataBuf.resize(size, 0);
file.read((char*)&m_dataBuf[0], size);
formatMimeType(filePath);
return true;
}
return false;
}
size_t SimpleTools::LocalFileReader::Read(void* data_out, int& bytes_to_read)
{
if (m_bytesReadPos == m_dataBuf.size())
return 0;
if ((m_bytesReadPos + bytes_to_read) > m_dataBuf.size())
bytes_to_read = m_dataBuf.size() - m_bytesReadPos;
memcpy(data_out, &m_dataBuf[0] + m_bytesReadPos, bytes_to_read);
m_bytesReadPos += bytes_to_read;
return bytes_to_read;
}
std::string SimpleTools::LocalFileReader::MimeType()
{
return m_mimeType;
}
void SimpleTools::LocalFileReader::formatMimeType(const std::string& filePath)
{
size_t idx = filePath.find_last_of(".");
if (idx != -1) {
static std::map<std::string, std::string> extMimeTypeMap = {
{"html", "text/html"},
{"css","text/css"},
{"js","text/javascript"}
};
std::string ext = filePath.substr(idx + 1);
auto iter = extMimeTypeMap.find(ext);
if (iter != extMimeTypeMap.end()) {
m_mimeType = iter->second;
}
}
}