首页 > 技术文章 > idHTTP最简洁的修改和取得Cookie例子

94YY 2013-12-19 17:53 原文

procedure TForm1.Button1Click(Sender: TObject);
var
     HTTP: TidHTTP;
     html, s: string;
     i: integer;
begin
     HTTP := TidHTTP.Create(nil);
     try
      HTTP.HandleRedirects := True;
      HTTP.AllowCookies := True;
      HTTP.Request.CustomHeaders.Values['Cookie'] := 'abcd';//修改Cookie 抓包可见
      html := HTTP.Get('http://www.baidu.com/');
      s := 'Cookies: ';
      if HTTP.CookieManager.CookieCollection.Count > 0 then
        for i := 0 to HTTP.CookieManager.CookieCollection.Count - 1 do
          s := s + HTTP.CookieManager.CookieCollection.Items[i].CookieText;
      Memo1.Lines.Add(s);//取得Cookie
     finally
      FreeAndNil(HTTP);
     end;
end;
//------------------------------------
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdCookieManager, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdHTTP;
type
  TForm1 = class(TForm)
    IdHTTP1: TIdHTTP;
    IdCookieManager1: TIdCookieManager;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
 Params: TStringList;
 HTML, loginurl, myuser: String;
 count,i:integer;
 _cookies, cookies:tstringlist;
 ll:boolean;
 name,value:String;
 procedure setcookies;
 var j:integer; s:string;
 begin
   count:=cookies.count;
   s:='';
   for j:=1 to count do
   begin
     IdCookieManager1.AddCookie(cookies[j-1],IdHTTP1.url.Host);
     s:=s+'; '+cookies[j-1];
   end;
   if s<>'' then
   begin
     delete(s,1,2);
     s:=s+';';
     IdHTTP1.Request.CustomHeaders.Values['Cookie']:=s;
     IdHTTP1.Request.RawHeaders.Values['Cookie']:=s;
     //('Cookie'+IdHTTP1.Request.RawHeaders.NameValueSeparator+s);
   end;{}
 end;
 procedure extractcookie(cookie:string; var name,value:string);
 var i,k:integer;
 begin
   i:=pos('=',cookie);
   k:=pos(';',cookie);
   if k=0 then k:=length(cookie);
   if i>0 then
   begin
     name:=copy(cookie,1,i-1);
     value:=copy(cookie,i+1,k-i-1);
   end      else
   begin
     name:='';
     value:='';
   end;
 end;
 procedure savecookies;
 var j:integer;
 begin
   count:=IdCookieManager1.CookieCollection.count;
   for j:=1 to count do
   begin
     extractcookie(IdCookieManager1.CookieCollection.Items[j-1].CookieText,name,value);
     cookies.Values[name]:=value;
   end;
//   IdCookieManager1.CookieCollection.Clear;
 end;
 procedure saveit(name:string);
 begin
   with tfilestream.create(name,fmcreate) do
   try
     write(pansichar(html)^,length(html));
   finally
     free;
   end;
 end;
begin
  ll:=false;
  loginurl:='http://feedmelinks.com/login';
  Params := TStringList.Create;
  try
    cookies:=tstringlist.Create;
//    cookies.Duplicates:=dupIgnore;
//    cookies.Sorted:=true;
    idhttp1.Host:='feedmelinks.com';
    html:=idhttp1.Get('http://feedmelinks.com/');// first get; get first cookie(s)
    savecookies;
    setcookies;
    html:=idhttp1.Get(loginUrl);// next get; this is clean: used for retrieving the viewstate
    savecookies;
    myuser:='crystyignat';
    Params.Values['userId'] := myuser;
    Params.Values['password'] := 'mypassword';
    Params.Values['op'] := 'login';
    IdHTTP1.HandleRedirects:=false;// now this made the buzz, because the cookies were not set when following the redirect
    try
      setcookies;
      HTML := IdHTTP1.Post(loginurl, Params);// now do the log in
      _Cookies := TStringList.Create;
      IdHTTP1.Response.RawHeaders.Extract('Set-cookie', _Cookies);
      for i := 0 to _Cookies.Count - 1 do
      begin
//        IdCookieManager1.AddCookie(_Cookies[i], IdHTTP1.URL.Host);
        extractcookie(_Cookies[i],name,value);
        cookies.Values[name]:=value;
      end;
      _cookies.free;
//      savecookies;
      if pos('<div class="welcome">Welcome, <b>'+myuser+'</b>',html)>0 then
      begin
        setCookies;
        html:=idhttp1.Get('http://feedmelinks.com/'); // software redirect
        savecookies;
        saveit('hhh.html');
//        setCookies;
//        html:=idhttp1.Get('http://feedmelinks.com/portal'); // another software redirect
        //savecookies;
        ll:=pos('<a class="tn" href="logout">log out',html)>0;
      end;
    except on e: EIdHTTPProtocolException do
    begin
      if e.ReplyErrorCode<>302 then
         raise e;
        // now this is the redirect
        count:=IdCookieManager1.CookieCollection.count;// get the next cookie (this will be the userid)
        for i:=1 to count do
          cookies.Add(IdCookieManager1.CookieCollection.Items[i-1].CookieText);
        setcookies;
        html:=idhttp1.Get(IdHTTP1.Response.Location);// follow redirect
      end;
    end;
    cookies.free;
  except on e: EIdHTTPProtocolException do
    begin
      showmessage(idHTTP1.response.ResponseText);
    end;
  end;
  Params.Free;
  showmessage('logged in? : '+booltostr(ll,true));
end;
end.

  

推荐阅读