【问题标题】:Send file to website with Indy TIdTCPClient使用 Indy TIdTCPClient 将文件发送到网站
【发布时间】:2018-12-30 16:41:42
【问题描述】:

我需要正确的方式将带有TIdTCPClient 的文件发送到top4top 网站。

我使用TIdTCPClient 中的WriteFile() 选项发送它,但它不起作用,并使用流发送,但我收到一个错误的请求。

var
  utf8: IIdTextEncoding;
  sid,result: string;
  lParam: TIdMultiPartFormDataStream;
begin
  sid := 'Z2jAmKM%2CA8Ik2dJxlR9NlZUW65b';
  if OpenDialog1.Execute then
  begin
    utf8 := IndyTextEncoding_UTF8;
    lParam := TIdMultiPartFormDataStream.Create;
    lParam.AddFormField('sid', sid);
    lParam.AddFile('file_1_', OpenDialog1.FileName);
    lParam.AddFormField('submitr', '[ رفع الملفات ]');
    TCPC.host := 'up.top4top.net';
    TCPC.Port := 443;
    TCPC.ConnectTimeout := 100000;
    TCPC.ReadTimeout := 500000;
    TCPC.Connect;
    TCPC.Socket.WriteLn('POST /index.php HTTP/1.1');
    TCPC.Socket.WriteLn('Host: up.top4top.net');
    TCPC.Socket.WriteLn('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8');
    TCPC.Socket.WriteLn('Accept-Encoding: gzip, deflate, br');
    TCPC.Socket.WriteLn('Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7');
    TCPC.Socket.WriteLn('Content-Type: multipart/form-data; boundary=----   WebKitFormBoundarySSk63dIh0HIAto8S');
    TCPC.Socket.WriteLn('DNT: 1');
    TCPC.Socket.WriteLn('Origin: https://up.top4top.net');
    TCPC.Socket.WriteLn('Referer: https://up.top4top.net/');
    TCPC.Socket.WriteLn('Upgrade-Insecure-Requests: 1');
    TCPC.Socket.WriteLn('User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64)  AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36   OPR/57.0.3098.106');
    TCPC.Socket.Write(lParam);
    TCPC.Socket.WriteLn('');
    Result := TCPC.Socket.AllData(utf8);
    TCPC.Disconnect;
  end;

【问题讨论】:

  • 使用TIdHttp.Post 会更容易,尤其是加密(TLS)。
  • 谢谢,我可以通过 idhttp 或 tnethttpcient 轻松发送,但我想了解套接字以及如何使用它通过 idtcpclient 发送文件
  • 感谢您努力学习,但这似乎是在浪费时间,使用适当的组件可以在 5 分钟内解决您的所有问题,根本无需重新发明轮子。 Indy 附带源代码,如果您想学习,请阅读源代码并快速了解所有涉及您面临挑战的各种 RFC。
  • 谢谢先生 科学没有浪费时间
  • @NewBinary 如果您真的想以艰难的方式做到这一点,我建议您首先使用TIdHTTP 发送一个工作请求并使用TIdLog... 组件捕获其输出,然后使用复制相同的输出TIdTCPClient

标签: delphi tcpclient indy


【解决方案1】:

你犯了几个错误:

  1. 您在Content-Type 标头中指定的boundary 属性的值与编码其MIME 数据时TIdMultiPartFormDataStream 实际使用的值不匹配。您需要使用TIdMultiPartFormDataStream.RequestContentType 属性正确设置Content-Type 标头。否则服务器将无法正确解析数据。

  2. 您根本没有发送Content-Length 标头。需要告知服务器您发送了多少数据。

  3. 您对WriteLn('') 的调用必须在调用Write(lParam) 之前,而不是之后。 HTTP 消息的标头和正文由空行分隔。

试试这个:

var
  sid, result: string;
  lParam: TIdMultiPartFormDataStream;
begin
  sid := 'Z2jAmKM%2CA8Ik2dJxlR9NlZUW65b';
  if OpenDialog1.Execute then
  begin
    lParam := TIdMultiPartFormDataStream.Create;
    try
      lParam.AddFormField('sid', sid);
      lParam.AddFile('file_1_', OpenDialog1.FileName);
      lParam.AddFormField('submitr', '[ رفع الملفات ]', 'utf-8');

      TCPC.Host := 'up.top4top.net';
      TCPC.Port := 443;
      TCPC.ConnectTimeout := 100000;
      TCPC.ReadTimeout := 500000;

      // make sure you have an SSLIOHandler component
      // assigned to the TCPC.IOHandler property, and
      // its PassThrough property is set to False before
      // sending any data...
      TCPC.Connect;
      try
        // set PassThrough=False here if not already...

        TCPC.Socket.WriteLn('POST /index.php HTTP/1.1');
        TCPC.Socket.WriteLn('Host: up.top4top.net');
        TCPC.Socket.WriteLn('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8');
        TCPC.Socket.WriteLn('Accept-Encoding: gzip, deflate, br');
        TCPC.Socket.WriteLn('Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7');
        TCPC.Socket.WriteLn('Connection: close');
        TCPC.Socket.WriteLn('Content-Type: ' + lParam.RequestContentType);
        TCPC.Socket.WriteLn('Content-Length: ' + IntToStr(lParam.Size));
        TCPC.Socket.WriteLn('DNT: 1');
        TCPC.Socket.WriteLn('Origin: https://up.top4top.net');
        TCPC.Socket.WriteLn('Referer: https://up.top4top.net/');
        TCPC.Socket.WriteLn('Upgrade-Insecure-Requests: 1');
        TCPC.Socket.WriteLn('User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 OPR/57.0.3098.106');
        TCPC.Socket.WriteLn;
        TCPC.Socket.Write(lParam);

        Result := TCPC.Socket.AllData(IndyTextEncoding_UTF8);
      finally
        TCPC.Disconnect;
      end;
    finally
      lParam.Free;
    end;
  end;
  ...
end;

【讨论】:

  • 我的代码中的问题在于 TCPC.IOHandler.WriteLn('Content-Type: ' + lParam.RequestContentType); TCPC.IOHandler.WriteLn('内容长度:' + lParam.Size.ToString );我测试了它并工作了谢谢你我现在需要了解 cookie
  • 还有一个问题,如果这个站点需要像 sid 这样的令牌,例如我可以通过发送 get 方法来获取令牌并再次发送它还是有其他方法可以做到这一点 请为此站点举例通过使用 sid 字符串询问网站并再次发送谢谢
  • 这些是需要单独提出的新问题。
  • 谢谢你,我会尽快把它说出来谢谢你非常匹配:)
猜你喜欢
  • 1970-01-01
  • 2019-07-01
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
  • 1970-01-01
  • 2012-07-29
相关资源
最近更新 更多