Delphi 使用IdHTTP发布请求

Delphi 使用IdHTTP发布请求,delphi,Delphi,您好,我正在尝试使用组件IdHTTP POST方法填写表单,我的代码如下: var par2: TIdMultiPartFormDataStream; rta: string; begin par2 := TIdMultiPartFormDataStream.Create; par2.AddFormField('ipaddress', ip.text); par2.AddFormField('submit', 'Submit'); rta := id

您好,我正在尝试使用组件IdHTTP POST方法填写表单,我的代码如下:

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;
表格的代码如下:

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

您的IP地址:181.92.20.173
输入IP地址
问题是,我没有返回适当的响应表单,这使我返回的是空表单,好像他把它都搞错了一样


我做错了什么?

我再次检查了代码,似乎您不应该将其作为多部分表单数据发送。该网站不接受这一点。用这个

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;

您正在使用
TIdMultipartFormDataStream
提交web表单数据,该数据使用
multipart/formdata
格式发布数据。但是,HTML
标记没有
enctype=multipart/form data
属性,因此服务器不需要该格式。它希望使用默认的
应用程序/x-www-webform-urlencoded
格式提交数据。这是通过使用
TStrings
对象发布数据来实现的

下面的代码对我来说效果很好,它接收到一个HTML响应,其中包括IP地址查找的结果(在接收到该结果后必须对其进行解析):

据说,为了政治上正确,还有另外两个因素要考虑。如果您使用Wireshark之类的数据包嗅探器查看普通web浏览器提交的内容,您会注意到:

  • Web表单提交上有一个
    Referer
    标题,用于让服务器知道提交的来源。您正在忽略该标题。有时web服务器会验证
    Referer
    ,以确保请求实际上来自其自己的站点,而不是其他地方,因此您应该在适当的时候提供
    Referer

  • 服务器发送一个带有初始HTML的cookie,然后在提交webform时将其发送回服务器。有时,web服务器需要这些cookie来确保客户端在提交web表单数据之前访问了原始站点。因此,您应该下载初始HTML,让
    TIdHTTP
    获取任何必要的cookie,以便它可以将它们发送回服务器

  • 下面的代码对我来说也很好,接收相同的HTML响应,其中包括IP地址查找的结果:

    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;
    

    最后,您使用的是基于HTML的查找服务,这不是一个很好的决定。HTML是用来表示供人类使用的数据的,不适合机器解析。还有很多其他IP查找服务可用,它们提供了更高效的基于REST的API,以机器可解析的格式(如XML或JSON)提供结果。你应该认真考虑切换到这些服务中的一个。

    我假设这个代码> iPoCaso.ASP/COD>文件是由OP创建的。现在我知道不是这样。因为你的回答有效果。我删除了我的错误+1。因此,只有当一个人实际添加了一个文件或其他东西来创建多部分post请求时,多部分post方法才似乎有效。我添加了这个方法,以防有人难以理解为什么表单post不能与TIdMultiPartFormDataStream一起工作。如果不发送由多部分组成的表单,则使用标准TStringList作为IdHttp的参数。Post@AndreVanZuydam:正如我在回答中所解释的那样,
    TIdMultipartFormDataStream
    仅应在服务器实际需要时使用,例如HTML
    标记具有
    enctype=multipart/form data
    属性时。它不是专门用来发送文件的。@NickFuryy:这段代码对我来说很好(见我的答案)。返回的HTML包含查找结果数据。你期望得到什么样的结果,你实际上得到了什么样的结果?请更具体地说明您遇到的实际问题。我首先提供的代码有什么问题?据我所知,它返回正确的结果。请解释一下
    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;