我正在尝试修改TChromium的用户代理,如果它使用CefVCL,我没有发现任何程序。已经通过 ceflib 看起来它必须是的,我看到了一个变量"设置",它接收值"user_agent",但 VCL 已经有,将有或不可能这样?
没有内置的方法可以做到这一点。根据我的经验,用户代理设置什么都不做。所以你必须直接编辑 ceflib.pas(第 ~8532 行)才能达到这个效果。
settings.user_agent := cefstring(UserAgent);
成为:
settings.user_agent := cefstring('My USERAGENT v1.0');
综上所述,您可能希望包含自己的操作系统和浏览器信息,因为这会阻止CEF对这些变量的实现。或者附加它,如下所示:
settings.user_agent := cefstring(UserAgent+'; My UserAgent v1.0');
我就是这样做的。我已经使用DCEF1和DCEF3大约一年了。而且还在学习!
查看演示 guiclient 的项目源代码
begin
//CefCache := 'cache';
CefCache:='./ca1';
CefUserAgent:='"Mozilla/5.0(Linux; U; Android 4.0.4; zh-cn; MI-ONE C1 Build/IMM76D) UC AppleWebKit/534.31 (KHTML, like Gecko) Mobile Safari/534.31"';
CefOnRegisterCustomSchemes := RegisterSchemes;
CefSingleProcess := False;
if not CefLoadLibDefault then
Exit;
CefRegisterSchemeHandlerFactory('local', '', False, TFileScheme);
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.
ceflib.pas5549路
Var
UA: integer;
UAescojido: Ustring;
。
settings.cache_path := CefString(Cache);
UA:= Random(2)+1; //NEW LINE
if UA=1 then UAescojido:= 'xxxxxxxxxx'; //NEW LINE
if UA=2 then UAescojido:= 'xxxxxxxxxx'; //NEW LINE
settings.user_agent := cefstring(UAescojido); //ASSIGN VARIABLE
不是完全改变,但它对我有用。
procedure TForm1.Chromium1BeforeResourceLoad(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
const request: ICefRequest; const callback: ICefRequestCallback; out
Result: TCefReturnValue);
Var
map: ICefStringMultimap;
begin
map := TCefStringMultimapOwn.Create;
request.GetHeaderMap(map);
map.Append('User-Agent','Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16');
request.SetHeaderMap(map);
callback.Cont(true);
end;
我的 (C++) 实现分叉 CEF 并将以下方法添加到 CefRequestHandler:
virtual bool GetOverrideUserAgent(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> request_info,
CefString& overrideUserAgent) { return false; }
然后,在cef\libcef\common\request_impl.cc中:
void CefRequestImpl::Set(net::URLRequest* request) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
...
const content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
if (info) {
...
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if(browser) {
...
CefString overrideUserAgent;
if(request_handler->**GetOverrideUserAgent**(browser.get(),
request_info, overrideUserAgent)) {
headermap_.erase(
net::HttpRequestHeaders::kUserAgent);
headermap_.insert(
std::make_pair(net::HttpRequestHeaders::kUserAgent,
overrideUserAgent));
}
...
所以(基本)步骤是这些:1. 叉式 CEF2. 添加 CefRequestHandler::GetOverrideUserAgent3. 在您的应用程序中,客户端处理程序应从 CefRequestHandler 派生并实现 GetOverrideUserAgent4. 您的应用程序可以根据需要设置 UA。
然而,我就是这样做的。它可能不适合您的需求。
我们已经使用 DCEF1 好几年了,我们还没有升级到 DCEF3(因为它缺少我们需要的东西)。所以这个答案可能已经过时了,但它的价值是什么:
在DCEF1中,ciflib单元中有一个名为CefUserAgent的全局变量。我们在其中一个项目单元的初始化部分中将该变量设置为我们的客户用户代理字符串。这很简单,似乎对我们很有效。
CefUserAgent := OutCustomUserAgentString;
我现在不记得这种方法的派生(太久远了),但我希望我们只会在一个单元的初始化部分完成它,如果这是使其正常工作所必需的。
不幸的是,我不知道这是否仍然适用于 DCEF3。
在主程序单元的初始化部分中设置 CefUserAgent 变量。
initialization
CefUserAgent := "Your Agent";
另类:
如果您使用的 CEF 版本没有 CefUserAgent 全局变量,则可以尝试:
用户代理存储在
var
settings: TCefSettings;
在 ceflib 文件中,该文件在局部函数中声明,而不是全局变量。设置记录包含可以修改的变量settings.user_agent。
function CefLoadLib
是声明变量的位置,CefLoadLibDefault 调用 CefLoadLib。
将设置设置为单元文件顶部的全局设置,而不是将其保留为本地函数变量,可能是一种解决方案,以便您可以在将组件加载到窗体上之前在另一个单元的初始化部分中修改用户代理。 但是,由于全局变量在许多情况下是一件坏事,并且可能导致意想不到的后果......人们必须检查以确保进行这样的修改不会不安全。
如果尚未这样做,这应该是 delphi CEF 包含可在 vcl 组件中修改的用户代理设置的功能请求。有没有人要求此功能...还。。如果没有,那肯定是有用的。
另一个临时解决方案是使全局字符串变量而不是整个设置记录成为全局记录,并在设置用户代理时仅使用全局字符串变量:
settings.user_agent := cefstring(YourGlobalVariableHere);
这又不是一个永久的解决方案,这个功能应该真正在组件本身中实现。