开始前,先看下要实现的微信接口,,这个接口是用Form表单形式上传的文件。对我来说,对http的Form表单一知半解,还好,查到这个资料,如果你也和我一样,必须看看。
在的指导下,我使用了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;