Я пытаюсь войти на сайт через 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">
</td>
</tr>
<tr>
<td colspan="2" align="right">
<input id="submission" type="submit" class="button" name="sublogin" value="Login" /></td>
</tr>
Таким образом, значение кнопки отправки - это просто логин. Таким образом я не знаю, где POST данных. Как я могу это узнать? И как только я узнаю URL-адрес, я должен просто добавить его в idhttp1.Post
правильно?
Есть несколько проблем с вашим кодом:
вы не отправляете все, что находится в форме входа в систему. Вы должны это сделать. Это включает в себя значение самой кнопки входа, так как она имеет значения name
и id
. Для некоторых серверов это значение кнопки.
вы устанавливаете значение TIdHTTP.Request.ContentType
недопустимым значением. Однако, случается, что TIdHTTP.Post(TIdMultipartFormDataStream)
игнорирует предоставленный пользователем ContentType
и использует TIdMultipartFormDataStream.RequestContentType
свойство вместо этого. Таким образом, это не влияет на ваш логин, но он по-прежнему является ошибкой в вашем коде.
вы игнорируете кодировку ответов при загрузке данных ответа в TMemo
. Вы должны использовать перегруженную версию TIdHTTP.Post()
которая возвращает String
и присваивает это TMemo.Text
. Пусть TIdHTTP
обрабатывает декодирование кодировки для вас.
вы протекаете объект TIdMultipartFormDataStream
.
Попробуй это:
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 клиенту, когда он запрашивает страницу входа в систему, а затем эти куки должны быть отправлены обратно как часть процесса входа в систему. Если сама публикация в 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()
отправит вместо 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;
TIdHTTP.Post()
возвращает содержимое страницы ответа. Если он возвращается пустым, то либо нет содержимого для начала, либо произошла ошибка преобразования набора символов, в результате чего была пустая строка. Если ваш исходный код Post()
возвращал TStringStream
данные в вашем TStringStream
, но мой код возвращает пустую String
, то последний является виновником. Причина, по которой я избегаю TStringStream
заключается в том, что он требует, чтобы вы знали кодировку заранее, но вы не знаете, что это такое, пока ответ не будет получен. String
версия Post()
использует кодировку ответа для декодирования.
POST должен перейти на тот же URL-адрес, где вы извлекли HTML-страницу, поскольку атрибут действия пуст.
В зависимости от сервера успешный логин отправляет файлы cookie обратно клиенту, который должен быть включен в следующие запросы.
Используются файлы cookie Wether или нет, если вы анализируете связь между браузером и клиентом с Firebug или прокси-сервером HTTP, например, Fiddler.
Если сервер использует прокси-серверы, вам необходимо добавить поддержку файлов cookie для кода клиента. Indy поддерживает HTTP файлы прозрачно (TIdCookieManager).
user=someuser&pass=Somepass&sublogin=login
Нужно ли мне использовать это во втором посте после того, как я получу куки?
document.getElementById('submission').click();
Но как я могу назвать это из idhttp? Это javascript? как я не вижу функции, вызываемой нажмите на источник страницы