POST request with IdHTTP
Hey. I am trying to fill out a form using the POST method of the IdHTTP component, the code I have is:
var
par2: TIdMultiPartFormDataStream;
rta: string;
begin
par2 := TIdMultiPartFormDataStream.Create;
par2.AddFormField('ipaddress', ip.text);
par2.AddFormField('submit', 'Submit');
rta := idhttp1.Post
('http://www.melissadata.com/lookups/iplocation.asp?ipaddress=', par2);
memo.Lines.Add(rta);
end;
And the form code is like this:
<form method="post" action="iplocation.asp">
<table class="Tableresultborderblue" align="right" border="0" cellpadding="0" cellspacing="0" width="300">
<tbody><tr><td align="center"><span style="font-size:12px;">Your IP Address: 181.92.20.173</span></td></tr>
<tr><td align="center" height="35px"><strong>Enter an IP address</strong></td></tr>
<tr><td align="center"><input id="ipaddress" name="ipaddress" value="" class="inputoff" type="text"></td></tr>
<tr><td height="10"></td></tr>
<tr><td align="center" height="45px"><input title="Click to process Address" class="btn" value="Submit" type="submit"></td></tr>
<tr><td height="10"></td></tr>
</tbody></table>
</form>
The problem is that I am not returning the appropriate response form that returns me, it is an empty form as if it was wrong.
What am I doing wrong?
source to share
You are submitting data to a web form using TIdMultipartFormDataStream
, which submits data in multipart/form-data
. However, the HTML tag <form>
has no attribute enctype=multipart/form-data
, so the server does not expect this format. The data is expected to be sent using the application/x-www-webform-urlencoded
default format . This is achieved by publishing data using an object TStrings
.
The following code works fine for me, it gets an HTML response that includes the IP address lookup results (which you will have to parse after receiving):
var
PostData: TStringList;
rta: string;
begin
PostData := TStringList.Create;
try
PostData.Add('ipaddress='+ip.Text);
rta := IdHTTP1.Post('http://www.melissadata.com/lookups/iplocation.asp', PostData);
finally
PostData.Free;
end;
Memo1.Lines.Text := rta;
end;
That being said, to be politically correct, there are two other factors to consider. If you use a packet sniffer like Wireshark to see what a regular web browser is like, you will notice that:
-
there is a header
Referer
in the web form view so the server knows where the transfer originated from. You omit this heading. Sometimes web servers checkReferer
to make sure the request is actually coming from their site and not somewhere else, so you should provideReferer
it when needed. -
the server sends a cookie with the original HTML, which is then sent back to the server with the submission of the web form. Sometimes web servers require these cookies in order for the client to visit the original site before submitting the web form data. Therefore, you have to download the initial HTML to
TIdHTTP
get all the necessary cookies so that it can send them back to the server.
The following code works fine for me too, gets the same HTML response that includes the results of looking up the IP address:
var
PostData: TStringList;
rta: string;
begin
// Get webform HTML and any cookies that go with it
IdHTTP1.Get('http://www.melissadata.com/lookups/iplocation.asp');
// now post the webform data back to the server
PostData := TStringList.Create;
try
PostData.Add('ipaddress=23.241.61.8');
IdHTTP1.Request.Referer := 'http://www.melissadata.com/lookups/iplocation.asp';
rta := IdHTTP1.Post('http://www.melissadata.com/lookups/iplocation.asp', PostData);
finally
PostData.Free;
end;
Memo1.Lines.Text := rta;
end;
Finally, you are using an HTML based search service, which is not a good solution. HTML is designed to represent data for human consumption that is not suitable for machine parsing. There are many other IP lookup services that provide more efficient REST-based APIs for providing results in machine formats such as XML or JSON. You should seriously consider switching to one of these services.
source to share
I checked the code again, and it really seems like you shouldn't be submitting it as multiple form data. The site does not accept this. Use this
var
PostData: TStringList;
res: string;
begin
PostData:=TStringList.Create;
try
PostData.Add('ipaddress='+ip.text);
res:=IdHTTP1.Post('http://www.melissadata.com/lookups/iplocation.asp', PostData);
Memo1.Lines.Text:=res;
finally
PostData.Free;
end;
end;
source to share