2017-04-19 20 views
2

我想用代理使用Delphi VCL组件TWebBrowser。这似乎是很容易做这样的事情:Delphi 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; 

我得知InternetSetOption与像INTERNET_OPTION_PROXY_USERNAME参数可以仅适用于由类似功能所产生的互联网手柄InternetConnect或HttpOpenRequest。

关于此问题的答案可以在here找到。

这不是问题,我可以先拨打InternetConnect。但似乎是不可能的后绑定这个互联网句柄我的TWebBrowser。 TWebBrowser会忽略这些设置,因为它们适用于具体的专用互联网句柄。

所以我的问题:是否有可能在Delphi代码中使用身份验证设置代理以从TWebBrowser使用它?

PS。另一种选择是当TWebBrowser询问它们时记住登录/密码代理设置,但我有多个登录名/密码,所以我想从代码中设置它们。

先谢谢您。

+1

http://microsoft.public.inetsdk.programming.webbrowser-ctl.narkive.com/rgz718KC/how-to-pass-proxy-username-password-into-webbrowser-control –

+1

仅供参考,您的第一个代码片段是错误。你正在声明一个没有指向任何东西的未初始化的指针。你需要使用它:'var IInfo:InternetProxyInfo;开始IInfo.dwAccessType:= INTERNET_OPEN_TYPE_PROXY; ... UrlMkSetSessionOption(INTERNET_OPTION_PROXY,@IInfo,SizeOf(IInfo),0);结束;' –

+0

雷米Lebeau,是的,完全。其实我忘了在代码中添加这个代码片段:New(PIInfo); ..... Dispose(PInfo); –

回答

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; 

...之后它适用于web浏览器...

WebBrowser1.OnBeforeNavigate2 := WebBrowser1BeforeNavigate2; 

该方法是基于使用的标题Proxy-Authorization,允许定义代理凭据请求。它还需要首先使用第一篇文章中定义的UrlMkSetSessionOption来设置代理服务器和端口。

2.使用报头的方法中Navigate2

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.使用替代组件

我发现执行铬德尔福(在积极发展) - CEF4Delphi。它是基于DCEF3库似乎留下一点点。

它支持代理设置界面开箱即用。可以使用主浏览器对象的基本属性来定义代理服务器,端口,用户名和密码。

因此,如果使用TWebBrowser不一定是为了您的目的,您可以看看这个组件。