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

简介: 开始前,先看下要实现的微信接口,上传多媒体文件,这个接口是用Form表单形式上传的文件。对我来说,对http的Form表单一知半解,还好,查到这个资料,如果你也和我一样,必须看看这篇文章。 在xalion窑主的指导下,我使用了indy自带的TIdMultiPartFormDataStre am类,来提交上传的文件。

开始前,先看下要实现的微信接口,上传多媒体文件,这个接口是用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;


参考的原文地址在这里。
目录
相关文章
|
移动开发 Java
java发送post请求,使用multipart/form-data的方式传递参数
java发送post请求,使用multipart/form-data的方式传递参数
1456 0
|
7月前
|
自然语言处理 数据可视化 数据挖掘
Agent实操(四):Code Interpreter,生成二维码、视频、PDF转txt等炸裂功能
本文介绍Agent自带的Code Interpreter有哪些高级而实用的能力
Agent实操(四):Code Interpreter,生成二维码、视频、PDF转txt等炸裂功能
|
7月前
|
JavaScript
vue element upload组件配合axios实现用 “Content-Type“: “multipart/form-data“上传方式导入xls文件
vue element upload组件配合axios实现用 “Content-Type“: “multipart/form-data“上传方式导入xls文件
|
7月前
|
PHP
文件上传--Upload-labs--Pass16--图片二次渲染
文件上传--Upload-labs--Pass16--图片二次渲染
|
存储 JSON Android开发
大师学SwiftUI第17章Part2 - WebKit 框架和JSON等网页内容加载
对于某些应用,Safari视图控制器中包含的自定义选项还不够。为此Apple又提供WebKit框架这一选项。借助于这个框架,我们可以在视图内展示网页内容。该视图通过UIView类的子类WKWebView定义。这个类提供了如下管理内容的属性和方法。 •
128 0
|
JavaScript 前端开发
1024JS常用的对象总结(第十三课)主要内容String Date Math
1024JS常用的对象总结(第十三课)主要内容String Date Math
74 0
|
数据采集 Python
Python 文件上传:如何使用 multipart/form-data 编码和 requests 包
为 Python 标准库没有提供创建 multipart/form-data 编码类型请求的内置方法,这种编码类型允许发送二进制数据和其他表单字段。因此,在 Python 文件上传时,程序必须要么使用第三方库,要么手动构造请求体和头部。其中一个比较简单的方法是使用 requests 包(PyPI 链接),简单快捷的在 Python 3 中使用Requests 包,通过Multipart/Form-Data 编码并上传文件。
905 0
Python 文件上传:如何使用 multipart/form-data 编码和 requests 包
|
前端开发 JavaScript Java
【前端】form标签multipart/form-data 文件上传表单中 传递参数无法获取的原因
form标签multipart/form-data 文件上传表单中 传递参数无法获取的原因
1116 1
|
存储 C# Python
基于C#的ArcEngine二次开发46:编辑内容回撤与炸开multipart feature
基于C#的ArcEngine二次开发46:编辑内容回撤与炸开multipart feature
基于C#的ArcEngine二次开发46:编辑内容回撤与炸开multipart feature
|
前端开发
.NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
.NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
435 0
.NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数