zoukankan      html  css  js  c++  java
  • [转载红鱼儿]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;


    参考的原文地址在这里。
  • 相关阅读:
    Atitit. visual studio vs2003 vs2005 vs2008  VS2010 vs2012 vs2015新特性 新功能.doc
    Atitit. C#.net clr 2.0  4.0新特性
    Atitit. C#.net clr 2.0  4.0新特性
    Atitit.通过null 参数 反射  动态反推方法调用
    Atitit.通过null 参数 反射  动态反推方法调用
    Atitit..net clr il指令集 以及指令分类  与指令详细说明
    Atitit..net clr il指令集 以及指令分类  与指令详细说明
    Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
    Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
    Atitit.跨语言反射api 兼容性提升与增强 java c#。Net  php  js
  • 原文地址:https://www.cnblogs.com/xalion/p/4115277.html
Copyright © 2011-2022 走看看