• [转载红鱼儿]Delphi实现微信开发(3)如何使用multipart/form-data格式上传文件


    开始前,先看下要实现的微信接口,上传多媒体文件,这个接口是用Form表单形式上传的文件。对我来说,对http的Form表单一知半解,还好,查到这个资料,如果你也和我一样,必须看看这篇文章

    xalion窑主的指导下,我使用了indy自带的TIdMultiPartFormDataStre

    am类,来提交上传的文件。

    如果使用indy的idhttp,则调用这个方法,即可以提交Form.
    function Post(AURL: string; ASource: TIdMultiPartFormDataStream): string;

    在窑主的建议下,使用了TMS Sparkle组件,对TIdMultiPartFormDataStream进行提交。

    先实现下面这个函数,向指定网址提交TIdMultiPartFormDataStream对象:
    function PostForm(url: string; aSource: TIdMultiPartFormDataStream): string;
    var
      FClient: THttpClient;
      Req: THttpRequest;
      Resp: THttpResponse;
    //  buffer: TBytes;
    begin
      FClient := THttpClient.Create;
      Resp := nil;
      Req := FClient.CreateRequest;
      try
        Req.Uri := url;
        Req.Method := 'POST';
        Req.Headers.SetValue('content-type', aSource.RequestContentType);
        Req.SetContent(GetContentAsBytes(aSource));
        Resp := FClient.Send(Req);
        Result := TEncoding.UTF8.GetString(Resp.ContentAsBytes);
      finally
        FreeAndNil(Req);
        FreeAndNil(Resp);
        FreeAndNil(FClient);
      end;
    end;
    上述方法中,使用了GetContentAsBytes函数,把一个TStream转换为TBytes.这个函数是参考TMS Sparkle的实现改写的。
    function GetContentAsBytes(aSource: TStream): TBytes;
    const
      BufSize = 8192;
    var
      BytesRead: Integer;
      TotalRead: Integer;
    begin
      Setlength(Result, 0);
      TotalRead := 0;
      repeat
        Setlength(Result, Length(Result) + BufSize);
        BytesRead := aSource.Read(Result[TotalRead], BufSize);
        TotalRead := TotalRead + BytesRead;
      until BytesRead <> BufSize;
      Setlength(Result, TotalRead);
    end;

    最后,具体封装上传文件的接口。调用这个接口,以变参的方式,返回微信平台返回的结果。具体的实现过程,建立一个TIdMultiPartFormDataStream对象,叫FormData,再调用FormData.AddFile方法,将上传的文件加入其中。之后,利用上面实现的PostForm提交FormData对象,接下来,对微信平台返回的结果进行处理,并利用变参返回。

    procedure UploadMedia(access_token, aFilePath: string; var aType: string;
      var media_id: string; var Created_at: TDatetime; var errcode: Integer;
      var errmsg: string);
    var
      url: string;
      FormData: TIdMultiPartFormDataStream;
      r: string;
      jo: TjsonObject;
      jv: Tjsonvalue;
    begin
      url := Format
        ('http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s',
        [access_token, aType]);
      FormData := TIdMultiPartFormDataStream.Create;
      try
        FormData.AddFile('media', aFilePath);
        r := PostForm(url, FormData);
        jo := TjsonObject.ParseJSONValue(r) as TjsonObject;
        if jo.TryGetValue('media_id', jv) then
        begin
          aType := jo.GetValue('type').Value;
          media_id := jo.GetValue('media_id').Value;
          Created_at := DateUtils.UnixToDateTime(jo.GetValue('created_at')
            .Value.ToInteger, False);
          errcode := 0;
          errmsg := '';
        end
        else
        begin
          errcode := jo.GetValue('errcode').Value.ToInteger;
          errmsg := jo.GetValue('errmsg').Value;
        end;
      finally
        FreeAndNil(FormData);
      end;
    end;

    调用代码:
    procedure Twm.UploadMedia(id: integer; aFile, aType: string);
    var
      errcode: integer;
      errmsg: string;
      Created_at: TDateTime;
      stype, media_id: string;
    begin
      if not qUploadMedia.Active then
        qUploadMedia.Open;
      stype := aType;
      WX_Impl.UploadMedia(GetAccessToken(id.ToString), aFile, stype, media_id,
        Created_at, errcode, errmsg);
      if errcode = 0 then
      begin
        //写入本地表.
        qUploadMedia.AppendRecord([id, stype, media_id, Created_at, aFile]);
        webLogger.WriteLog('上传成功,media_id=:' + media_id + '  时间:' +
          DateToStr(Created_at) + ' Type:' + sType)
      end
      else
        webLogger.WriteLog('上传失败:' + errcode.ToString + ':' + errmsg);
    end;


    参考的原文地址在这里。
  • 相关阅读:
    Project和Module的介绍
    2016-10-27~2016-11-12面试总结
    读写分离的概念(转)
    hashmap和hashtable,arraylist和vector的区别
    如何删除数据库表的重复数据
    Iterator和ListIterator的区别
    性能提升
    Oracle 查询并修改
    oracle数据库中VARCHAR2(50 CHAR) 和VARCHAR2(50) 有啥区别?
    SQL SERVER 2000安装教程图文详解
  • 原文地址:https://www.cnblogs.com/xalion/p/4115277.html
Copyright © 2020-2023  润新知