使用idhttp登录网站

时间:2014-07-09 06:27:27

标签: html delphi delphi-xe2 indy indy10

我正在尝试通过delphi / indy登录网站。目前我只有一个按钮(用于发送密码/用户名),它调用此程序。

procedure TForm5.Login(name: string; Pass: string);
var
UserID :string;
Password :string;
res :TStringStream;
details :Tstringlist;
multiformupload: TIdMultiPartFormDataStream;
begin
//create ini file to hold password / usesr name
        UserID:=name;
        Password:=pass;

        Res  := TStringStream.Create();
        MultiFormUpload := TIdMultiPartFormDataStream.Create;

        MultiFormUpload.AddFormField('user',UserID);
        MultiformUpload.AddFormField('pass',Password);
        idhttp1.Request.ContentType := '8bit';
        //idhttp1.Get('http://codeelf.com',res);
        idhttp1.Post('http://codeelf.com/games/the-grid-2/grid',Multiformupload,res);
        memo1.Lines.LoadFromStream(res);

        res.Free;
end;

当我查看网站代码时,我有这个。

 <form id="gridForm" action="" method="post" onsubmit="return checkLoginForm()">
      <table align="left" border="0" cellspacing="2" cellpadding="2">
         <tr>
            <td align="left" id="my_username">Username:</td>
            <td align="right"><input type="text" id="user" name="user" maxlength="12" autocomplete="off" /></td>
         </tr>
         <tr>
            <td align="left" id="my_password">Password:</td>
            <td align="right"><input type="password" id="pass" name="pass" maxlength="20" /></td>
         </tr>
         <tr>
            <td colspan="2" align="right">
              &nbsp;</td>
         </tr>
         <tr>
            <td colspan="2" align="right">
               <input id="submission" type="submit" class="button" name="sublogin" value="Login" /></td>
         </tr>

因此提交按钮值只是登录。因此,我不知道POST数据的位置。我怎么能找到这个?一旦我找到了网址,我应该能够将其添加到idhttp1.Post正确吗?

2 个答案:

答案 0 :(得分:2)

您的代码存在一些问题:

  1. 您没有提交登录表单中的所有内容。你必须这样做。这包括登录按钮本身的值,因为它分配了nameid值。有些服务器需要按钮值。

  2. 您将TIdHTTP.Request.ContentType设置为无效值。但是,TIdHTTP.Post(TIdMultipartFormDataStream)忽略用户提供的ContentType并使用TIdMultipartFormDataStream.RequestContentType属性。所以这不会影响您的登录,但它仍然是您的代码中的错误。

  3. 在将响应数据加载到TMemo时,您忽略了响应的字符集。您应该使用返回TIdHTTP.Post()的重载版String并将其分配给TMemo.Text属性。让TIdHTTP为您处理字符集解码。

  4. 您正在泄漏TIdMultipartFormDataStream对象。

  5. 试试这个:

    procedure TForm5.Login(name: string; Pass: string);
    var
      MultiFormUpload: TIdMultiPartFormDataStream;
    begin
      MultiFormUpload := TIdMultiPartFormDataStream.Create;
      try
        MultiFormUpload.AddFormField('user', name);
        MultiFormUpload.AddFormField('pass', pass);
        MultiFormUpload.AddFormField('sublogin', 'Login');
    
        //IdHTTP1.Get('http://codeelf.com');
        Memo1.Text := IdHTTP1.Post('http://codeelf.com/games/the-grid-2/grid', MultiFormUpload);
      finally
        MultiFormUpload.Free;
      end;
    end;
    

    话虽这么说,有些服务器在请求登录页面时向客户端发送cookie,然后这些cookie需要在登录过程中发回。如果单独发布到登录URL不起作用,请先尝试检索登录页面,然后发布登录凭据,让TIdHTTP为您处理cookie:

    procedure TForm5.Login(name: string; Pass: string);
    var
      MultiFormUpload: TIdMultiPartFormDataStream;
    begin
      MultiFormUpload := TIdMultiPartFormDataStream.Create;
      try
        MultiFormUpload.AddFormField('user', name);
        MultiFormUpload.AddFormField('pass', pass);
        MultiFormUpload.AddFormField('sublogin', 'Login');
    
        IdHTTP1.Get('http://codeelf.com/games/the-grid-2/grid', TStream(nil));
        Memo1.Text := IdHTTP1.Post('http://codeelf.com/games/the-grid-2/grid', MultiFormUpload);
      finally
        MultiFormUpload.Free;
      end;
    end;
    

    更新:原始代码还有其他问题。 HTML登录表单不会要求multipart/form-data帖子开头,因此TIdMultipartFormDataStream是使用的错误类。请改用TStringList,以便TIdHTTP.Post()发送application/x-www-form-urlencoded帖子:

    procedure TForm5.Login(name: string; Pass: string);
    var
      Params: TStringList;
    begin
      Params := TStringList.Create;
      try
        Params.Add('user='+name);
        Params.Add('pass='+pass);
        Params.Add('sublogin=Login');
    
        //IdHTTP1.Get('http://codeelf.com');
        Memo1.Text := IdHTTP1.Post('http://codeelf.com/games/the-grid-2/grid', Params);
      finally
        Params.Free;
      end;
    end;
    

答案 1 :(得分:1)

POST必须转到您检索HTML页面的同一URL,因为action属性为空。

根据服务器的不同,成功登录会将cookie发送回客户端,需要包含在下一个请求中。

如果您使用Firebug或Fiddler等HTTP代理工具分析浏览器/客户端通信,则可以找到或不使用更好的cookie。

如果服务器使用代理,则需要为客户端代码添加cookie支持。 Indy透明地支持HTTP cookie(TIdCookieManager)。