星五博客

TNetHttpClient上传文件

Delphi如何实现multipart/form-data方式上传文件呢?以前我们是使用indy,也就是用idHttp加TIdMultiPartFormDataStream来实现;本着研究精神,今天看了一下TNetHttpClient的定义,发现有个function Post(const AURL: string; const ASource: TMultipartFormData; const AResponseContent: TStream = nil;  const AHeaders: TNetHeaders = nil): IHTTPResponse; overload;的定义,然后官网查看了一下TMultipartFormData的说明,确认TNetHttpClient是可以独立完成formdata方式上传文件操作的,实验代码如下:

uses System.Net.Mime, // 用于支持 TMultipartFormData
  System.Net.HttpClientComponent; // 用于支持 TNetHTTPClient

procedure TfrmMain.Button1Click(Sender: TObject);
var
  cHttp: TNetHTTPClient;
  vData: TMultipartFormData;
  vRsp: TStringStream;
begin
  if OpenDialog1.Execute then
  begin
    cHttp := TNetHTTPClient.Create(nil);
    vData := TMultipartFormData.Create;
    vRsp := TStringStream.Create('', TEncoding.GetEncoding(65001));
    try
      vData.AddFile('fname', OpenDialog1.FileName);
      with cHttp do
      begin
        ConnectionTimeout := 2000; // 2秒
        ResponseTimeout := 10000; // 10秒
        AcceptCharSet := 'utf-8';
        AcceptEncoding := '65001';
        AcceptLanguage := 'zh-CN';
        ContentType := 'multipart/form-data';
        UserAgent := 'Embarcadero URI Client/1.0';
        try
          Memo1.Lines.Add('尝试上传文件 ' + OpenDialog1.FileName);
          Post('https://www.offeu.com/upfile', vData, vRsp);
          Application.ProcessMessages;
        except
          on E: Exception do
            // Error sending data: (12002) 操作超时.
            // Error receiving data: (12002) 操作超时
            if Copy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error sending data'
            then
              Memo1.Lines.Add('Error:连接失败!')
            else if Copy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error receiving data'
            then
              Memo1.Lines.Add('Error:接收失败,请延长接收超时时间!')
            else
              Memo1.Lines.Add('Error:' + E.Message);
        end;
        Memo1.Lines.Add(vRsp.DataString);
      end;
    finally
      cHttp.Free;
      vRsp.Free;
      vData.Free;
    end;
  end;
end;

我拿自己的网站的formdata接口进行了测试,上传文件很稳定。

不过,有个问题,因为emb官方没有提供数据发送的定义,所以无法实现上传进度的显示,但针对下载这块,又提供了,所以只能显示下载进度。

Delphi