我想将Delphi VCL组件TWebBrowser与代理一起使用。做这样的事情似乎很容易:
var PIInfo: PInternetProxyInfo;
begin
PIInfo^.dwAccessType := INTERNET_OPEN_TYPE_PROXY;
PIInfo^.lpszProxy := PAnsiChar('proxyserver.com:8888');
PIInfo^.lpszProxyBypass := PAnsiChar('');
UrlMkSetSessionOption(INTERNET_OPTION_PROXY, PIInfo, SizeOf(Internet_Proxy_Info), 0);
end;
但我也想使用代理进行身份验证。在这里我遇到了麻烦。我了解到可以使用WinAPI函数InternetSetOption设置代理名称和密码,如下所示:
var UserName: AnsiString;
ConnectionHandle: HINTERNET;
begin
// Init ConnectionHandle here
//...
res := InternetSetOption(ConnectionHandle,
INTERNET_OPTION_PROXY_USERNAME,
UserName,
Length(UserName) + 1);
end;
我了解到使用INTERNET_OPTION_PROXY_USERNAME等参数的InternetSetOption只能应用于InternetConnect或HttpOpenRequest等函数生成的Internet句柄。
可以找到关于此问题的答案here。
这不是问题,我可以先调用InternetConnect。但似乎不可能将此互联网句柄绑定到我的TWebBrowser。 TWebBrowser将忽略这些设置,因为它们适用于具体的专用互联网句柄。
所以我的问题是:是否可以在Delphi代码中使用身份验证设置代理以从TWebBrowser中使用它?
PS 即可。另一种选择是在TWebBrowser请求时记住登录/密码代理设置,但我有多次登录/密码,所以我想从代码中设置它们。
先谢谢你。
答案 0 :(得分:0)
David Heffernan的评论迫使我走向正确的方向。回答我自己的问题,万一有人会在寻找答案,我找到了解决这个问题的三个方法。
所有代码段都可用于 Delphi XE4 。
<强> 1。在TWebBrowser中使用事件处理程序。
TWebBrowser有事件OnBeforeNavigate2
。此方法的过程包含字段Headers
。所以我们可以定义一些方法,如:
procedure TForm1.WebBrowser1BeforeNavigate2(ASender: TObject;
const pDisp: IDispatch;
const URL: OleVariant;
const Flags: OleVariant;
const TargetFrameName: OleVariant;
const PostData: OleVariant;
const Headers: OleVariant;
var Cancel: WordBool);
var aHeaders: OleVariant;
begin
if ASender = WebBrowser1 then begin
if ALPos('X-StopHandling', Headers) <= 0 then begin
aHeaders := Headers + 'Proxy-Authorization: BASIC BASE64_of_login_and_password' + #13#10 +
'X-StopHandling: 1' + #13#10;
WebBrowser1.Navigate2(URL, Flags, TargetFrameName, PostData, aHeaders);
Cancel := true;
end;
end;
end;
...并将其应用于WebBrowser ...
WebBrowser1.OnBeforeNavigate2 := WebBrowser1BeforeNavigate2;
此方法基于使用标头Proxy-Authorization
,该标头允许为请求定义代理凭据。它还需要首先使用第一篇文章中定义的UrlMkSetSessionOption
设置代理服务器和端口。
<强> 2。在方法Navigate2中使用headers参数
TWebBrowser的方法Navigate2支持参数Headers
。因此,我们可以在调用此方法时定义相同的标头Proxy-Authorization
。这种方式的问题是,Navigate2的所有内部调用(如果页面上的某些Javascript将通过AJAX调用某些内容)将没有此标题。
第一种解决方案没有这个缺点。
代码段在这里:
var EmptyParam: OleVariant;
//...
begin
// init proxy server and port first as described in the first post
EmptyParam := System.Variants.EmptyParam;
WebBrowser1.Navigate2('http://something',
EmptyParam{Flags},
EmptyParam{TargetFrameName},
EmptyParam{PostData},
'Proxy-Authorization: ...' + #13#10);
end;
第3。使用替代组件
我发现了Delphi的Chromium实现(在积极开发中) - CEF4Delphi 。它基于 DCEF3 库,似乎有点遗留。
它支持开箱即用的代理设置界面。可以使用主浏览器对象的基本属性来定义代理服务器,端口,用户名和密码。
因此,如果使用TWebBrowser不一定是出于您的目的,您可以查看此组件。