delphi 使用idhttp+TIdMultiPartFormDataStream 上传表单post文件并解决ssl问题

Posted 记性不太好,特别需要这么一个博客!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi 使用idhttp+TIdMultiPartFormDataStream 上传表单post文件并解决ssl问题相关的知识,希望对你有一定的参考价值。

delphi 使用idhttp+TIdMultiPartFormDataStream 上传表单post文件并解决ssl问题

 

最近工作需要对接企业微信的推送信息接口

里面有发文件的功能

所以特地记录下上传文件并且使用idhttp遇到的访问ssl网址报错问题

参考文档:https://blog.csdn.net/huohuotu/article/details/77337087

官方上传临时素材文档:https://work.weixin.qq.com/api/doc/90000/90135/90253

下面不多说,直接贴上代码

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function xxx.UploadFile(const sAccessToken, sFile, sFileType: string):string;
var
  IdHttp: TIdHTTP;
  MutPartForm: TIdMultiPartFormDataStream;
  Ms: TStringStream;
  sTmp: string;
begin
  Result := \'\';
  try
    Ms := TStringStream.Create(\'\', TEncoding.UTF8);
    IdHttp := TIdHttp.Create(nil);
    IdHttp.ReadTimeout := 30000;
    MutPartForm := TIdMultiPartFormDataStream.Create;
    try
      IdHttp.AllowCookies    := True;
      IdHttp.HandleRedirects := True; //允许重定向
      // Http1.1
      IdHttp.HTTPOptions := IdHttp.HTTPOptions + [hoKeepOrigProtocol];
      IdHttp.ProtocolVersion := pv1_1;
      //MutPartForm.AddFormField(\'file\', sFile);
      sTmp := Format(\'http://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s\',[sAccessToken, sFileType]);
      IdHttp.Post(sTmp, MutPartForm, Ms);
      Result := Ms.DataString;
    finally
      Ms.Free;
      IdHttp.Free;
      MutPartForm.Free;
    end;
  except
    on E: Exception do Result := E.Message;
  end;
end;

  

但是这段代码会遇到两个问题:

1:发送的文件显示了完整的路径和文件名

2:有时候会报 IOHandler value is not valid错误

当然,如果你不在意文件名并且没有遇到这个报错问题的话,可以用这段代码

下面是解决这两个问题的改进版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
function xxx.UploadFile(const sAccessToken, sFile, sFileType: string):string;
var
  IdHttp: TIdHTTP;
  MutPartForm: TIdMultiPartFormDataStream;
  Ms: TStringStream;
  sTmp: string;
  LStream: TIdReadFileExclusiveStream;
  SSLIO: TIdSSLIOHandlerSocketOpenSSL;
begin
  Result := \'\';
  try
    Ms := TStringStream.Create(\'\', TEncoding.UTF8);
    IdHttp := TIdHttp.Create(nil);
    IdHttp.ReadTimeout := 30000;
    MutPartForm := TIdMultiPartFormDataStream.Create;
    LStream := TIdReadFileExclusiveStream.Create(sFile);
    SSLIO := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    try
      IdHttp.AllowCookies    := True;
      IdHttp.HandleRedirects := True; //允许重定向
      SSLIO.SSLOptions.Method:=sslvTLSv1;
      SSLIO.SSLOptions.Mode := sslmClient;
      IdHttp.IOHandler := SSLIO;
      // Http1.1
      IdHttp.HTTPOptions := IdHttp.HTTPOptions + [hoKeepOrigProtocol];
      IdHttp.ProtocolVersion := pv1_1;
      MutPartForm.AddObject(\'media\', \'application/octet-stream\', LStream, ExtractFileName(sFile));
      sTmp := Format(\'http://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s\',[sAccessToken, sFileType]);
      IdHttp.Post(sTmp, MutPartForm, Ms);
      Result := Ms.DataString;
    finally
      LStream.Free;
      Ms.Free;
      IdHttp.Free;
      MutPartForm.Free;
      SSLIO.Free;
    end;
  except
    on E: Exception do Result := E.Message;
  end;
end;

  

 需要增加uses引用的单元:IdGlobal, IdHTTP, IdMultipartFormData, IdSSLOpenSSL

 三个参数 ,获取的access_token, 文件路径,和文件类型,

文件类型:分别有图片(image)、语音(voice)、视频(video),普通文件(file)

delphi使用idhttp.post登录时网页使用gbk编码,但是idhttp自动将数据用utf-8编码。

主要代码如下:
HTTP.Request.UserAgent := '';
res := TMemoryStream.Create;
postData := TStringList.Create;
HTTP.Request.ContentType := 'application/x-www-form-urlencoded';
HTTP.Request.CharSet := 'GBK';
HTTP.Request.UserAgent := 'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 ( .NET CLR 3.5.30729)';
HTTP.HandleRedirects := true;

postData.Add('TPL_username=XXXXXX); //这里使用中文
postData.Add('&TPL_password=xxxxxxx);
postData.Add('&action=Authenticator');
postData.Add('&event_submit_do_login=anything');

HTTP.Post('https://login.taobao.com/member/login.jhtml', postData, res);

还试了将HTTPOptions的hoForceEncodeParams设为false,然后postData.Add('TPL_username=‘【转换好的字符串】’);,也不行。
改用Tstringstream还是不行。
HTTP.Post('https://login.taobao.com/member/login.jhtml', postData, res);
postData.SaveToFile('xxx.txt');
看了一下postData倒是对了,保存出来的串直接复制到地址栏里就能登录,但用我写的客户端就登录不了。我的这段登录代码有什么问题么?

参考技术A 声明postData为Tstringstream;
然后postData.writestring();添加参数

以上是关于delphi 使用idhttp+TIdMultiPartFormDataStream 上传表单post文件并解决ssl问题的主要内容,如果未能解决你的问题,请参考以下文章

Delphi IDHTTP控件:GET/POST 请求

Delphi IDHTTP控件:GET/POST 请求

delphi中IdHTTP控件怎么实现下载

delphi 7中使用idhttp抓取网页 解决假死现象

delphi使用idhttp.post登录时网页使用gbk编码,但是idhttp自动将数据用utf-8编码。

delphi 使用idhttp+TIdMultiPartFormDataStream 上传表单post文件并解决ssl问题