我的 post tidtcpclient 哪里出错了?

Where is the error in my post tidtcpclient?

我收到错误请求我的代码有什么问题

procedure TForm1.Button1Click(Sender: TObject);
begin
  TCPClient1.Host :='aavtrain.com';
  TCPClient1.Port := 80;
  TCPClient1.ConnectTimeout := 10000;
  TCPClient1.OnConnected := TCPClient1Connected;
  TCPClient1.ReadTimeout := 5000;
  TCPClient1.Connect;
end;

procedure TForm1.TCPClient1Connected(Sender: TObject);
var
  s: string;
begin
  //
  TCPClient1.Socket.WriteLn('POST HTTP/1.1');
  TCPClient1.Socket.WriteLn(sLineBreak);
  IdTCPClient1.Socket.WriteLn('http://aavtrain.comindex.asp');
  IdTCPClient1.Socket.WriteLn(sLineBreak);
  TCPClient1.Socket.WriteLn('user_name=binary');
  TCPClient1.Socket.WriteLn('&password=12345');
  TCPClient1.Socket.WriteLn('&Submit=Submit');
  TCPClient1.Socket.WriteLn('&login=true');
  TCPClient1.Socket.WriteLn(sLineBreak);
  repeat
    s := TCPClient1.Socket.ReadLn('');
    Memo1.Lines.Add(s);
  until s.Contains('try again');
  TCPClient1.Disconnect;
end;

您的 HTTP 消息完全格式错误,您发送到服务器的每一行都是错误的。


一条 HTTP 消息由三部分组成 - 一行 request/response,紧接着是 header,然后是 body。 header 和 body 由单个 CRLF CRLF 序列分隔,但您在 POST 请求行之后发送了一个 CRLF CRLF CRLF 序列。事实上,一般来说,您发送的换行符太多了。

POST 行本身缺少所请求资源的路径。

您根本没有发送任何 HTTP header。您正在请求 HTTP 1.1,它 需要 Host header。而且您没有发送 Content-Type header 所以服务器知道您发布的数据类型,或者 Content-Length header 所以服务器知道您发布了多少数据.

消息 body 本身也是格式错误的。您需要将网络表单值作为单行发送,而不是将每个值作为单独的行发送。

试试这个:

procedure TForm1.Button1Click(Sender: TObject);
var
  PostData, Response: string;
  Enc: IIdTextEncoding;
begin
  PostData := 'user_name=binary&password=12345&Submit=Submit&login=true';
  Enc := IndyTextEncoding_UTF8;
  //
  TCPClient1.Host := 'aavtrain.com';
  TCPClient1.Port := 80;
  TCPClient1.ConnectTimeout := 10000;
  TCPClient1.ReadTimeout := 5000;
  TCPClient1.Connect;
  try
    TCPClient1.Socket.WriteLn('POST /index.asp HTTP/1.1');
    TCPClient1.Socket.WriteLn('Host: aavtrain.com');
    TCPClient1.Socket.WriteLn('Content-Type: application/x-www-form-urlencoded; charset=utf-8');
    TCPClient1.Socket.WriteLn('Content-Length: ' + IntToStr(Enc.GetByteCount(PostData)));
    TCPClient1.Socket.WriteLn('Connection: close');
    TCPClient1.Socket.WriteLn;
    TCPClient1.Socket.Write(PostData, Enc);

    // the following is NOT the right way to read
    // an HTTP response. This is just an example.
    // I'll leave it as an exercise for you to
    // research and figure out the proper way.
    // I've posted pseudo code for this on
    // Whosebug many times before...
    Response := TCPClient1.Socket.AllData;
  finally
    TCPClient1.Disconnect;
  end;
  Memo1.Text := Response;
end;

请阅读 RFC 2616 and related RFCs, as well as W3C specs on HTML webform submissions (see HTML 4.01 and HTML5),因为很明显您不了解 HTTP 的实际工作原理。从头开始实施所有内容并非易事,因为它是一个非常复杂且涉及的协议。