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?

+3


source to share


2 answers


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 check Referer

    to make sure the request is actually coming from their site and not somewhere else, so you should provide Referer

    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.

+7


source


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;

      

+1


source







All Articles