从Webbrowser传输身份验证到Indy CookieManager

时间:2012-11-05 16:08:07

标签: delphi delphi-xe2

如何将来自Webbrowser的cookie放入Indy CookieManager以获取Http请求。

我登录这样的网站后得到了cookies ..

测试项目= http://www.megafileupload.com/en/file/373536/Cookie-Tester-rar.html

procedure TForm1.WebBrowser1DownloadComplete(Sender: TObject);
var
document: IHTMLDocument2;
cookies:tstringlist;
begin
cookies:=tstringlist.Create;
document := WebBrowser1.Document as IHTMLDocument2;
cookies.Add(document.cookie);
cookies.savetofile('test.txt');
end;

HttpOnly Cookie方法。

function GetCookie(host: PAnsiChar): PAnsiChar;
const
  INTERNET_COOKIE_HTTPONLY = 8192;
var
  hModule: THandle;
  lp: Pointer;
  InternetGetCookieEx: function(lpszUrl, lpszCookieName, lpszCookieData
    : PAnsiChar; var lpdwSize: DWORD; dwFlags: DWORD; lpReserved: pointer)
    : BOOL; stdCall;
  CookieSize: DWORD;
  CookieData: PAnsiChar;
begin
  LoadLibrary('wininet.dll');
  hModule := GetModuleHandle('wininet.dll');
  if hModule <> 0 then
  begin
    @InternetGetCookieEx := GetProcAddress(hModule, 'InternetGetCookieExA');
    if @InternetGetCookieEx <> nil then
    begin
      CookieSize := 1024;
      Cookiedata := AllocMem(CookieSize);
      if InternetGetCookieEx(host, nil, Cookiedata, CookieSize, INTERNET_COOKIE_HTTPONLY, nil) then
      result:=cookiedata;
      FreeMem(Cookiedata);
    end;
  end;
end;

1 个答案:

答案 0 :(得分:3)

由于您使用多个Delphi版本标记标记了您的问题,我假设您在每个Delphi版本中使用不同版本的Indy,是吗? Indy的cookie处理逻辑在过去几年中发生了一些变化,并在2011年初进行了重大改写,以便考虑RFC 6265(已废弃所有以前的cookie RFC)。

根据当前的Indy 10版本,使用TIdCookieManager.AddServerCookie()TIdCookieManager.AddServerCookies()方法手动添加Cookie:

procedure AddServerCookie(const ACookie: String; AURL: TIdURI);
procedure AddServerCookies(const ACookies: TStrings; AURL: TIdURI);

这两个参数都是必需的,其中ACookie是单个cookie的name=value; parameters字符串,AURL是cookie来自的URL(用于验证cookie数据和初始化)任何需要的默认值),例如:

procedure TForm1.WebBrowser1DownloadComplete(Sender: TObject);
var
  document: IHTMLDocument2;
  cookies: TStringList;
  uri: TIdURI;
begin
  document := WebBrowser1.Document as IHTMLDocument2;
  cookies := TStringList.Create;
  try
    // fill cookies as needed, one cookie per line
    uri := TIdURI.Create(document.URL);
    try
      IdCookieManager1.AddServerCookies(cookies, uri);
    finally
      uri.Free;
    end;
  finally
    cookies.Free;
  end;
end;

请注意,document.cookie属性中可能包含多个Cookie,因此您必须先手动拆分Cookie,然后才能将其传递给TIdCookieManager。此外,document.cookie属性使用;字符分隔Cookie,但它也使用';'用于分隔单个cookie的name=valueparameters值,因此在分割document.cookie数据时您将不得不进行一些解析。