好久没摸delphi xe 10.3.3,求大神用TIDHTTP获取到token之后无法获取数值,报Connection Closed Gracefully

yuzhizhi 2021-04-12 10:43:28
function TForm1.PostMethod(Url: String; Data: UTF8String; Max: Integer): String;
var
PostData, RespData: TStringStream;
HTTP: TIdHTTP;
SSL: TIdSSLIOHandlerSocketOpenSSL;
begin
RespData := TStringStream.Create('');
PostData := TStringStream.Create(Data); //个人判断这里TStringStream.create('data')不启作用
SSL := TIdSSLIOHandlerSocketOpenSSL.Create;
HTTP := TIdHTTP.Create;
HTTP.HandleRedirects := true;
HTTP.IOHandler := SSL;
try
try
if HTTP = nil then
Exit;
HTTP.Post(Url, PostData, RespData); //这里报错点 Connection Closed Gracefully.
Result :=Utf8ToAnsi( RespData.DataString);
HTTP.Request.Referer := Url;
except
on e: Exception do
begin
AddLog(e.Message); //这里是写入日志,忽略掉
Dec(Max);
if Max = 0 then
begin
Result := '';
Exit;
end;
Result := PostMethod(Url, Data, Max);
end;
end;
finally
HTTP.Disconnect;
HTTP.Free;
SSL.Free;
FreeAndNil(RespData);
FreeAndNil(PostData);
end;
end;



procedure TForm1.GetToken;
var
Url,Access_Token,StrJson,results: string;
Expires_IN:integer;
Root,Data: TJSONObject;
node: IXMLNode;
ParamsStr: string;
LDocument: IXMLDocument;
Paramslist: TStringList;
SValue:String;
begin
URL:=TokenUrl;
LDocument := TXMLDocument.Create(nil);
LDocument.LoadFromXML(GetMethod (URL,1));
node := LDocument.DocumentElement;
ReadXml(node,'token' ,ParamsStr); //成功抓取到Token--自定义过程获取服务器返回信息转成XML,并取出中的token值
Paramslist := TStringList.Create;
try
Paramslist.Text := ParamsStr; //把token值 数据传成数组 token值 为【Azh18=】
SValue:='&memberid=13455216875';
URL:=QueryVIPValue+Paramslist.Text; //URL结果为---http://12.227.110.23:801/api/memV/query?access-token=Azh18=
Data:= TJSONObject.Create;
try
Data.AddPair('Member','13455216875');
Memo2.Text:=PostMethod(URL, UTF8Encode(Data.ToString), 1); //断点这里报错{Connection Closed Gracefully},应该是postmethod 方法内出现,看上面。
finally
Data.Free;
end;
finally
Paramslist.Free;
end;

end;

服务环境如下:
服务器接口定义:
请求方式:POST
请求地址:/api/memV/query
参数说明:
名称 类型 必须 描述
memV String true 会员卡号
返回参数
名称 类型 描述
code number 返回代码
message string 返回信息
amount number 余额
请求示例
{"memv":"13455216875"}

返回示例
{“code”:0,
"message":"ok",
"amount": 50
...全文
1283 21 打赏 收藏 举报
写回复
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuzhizhi 2021-05-06
  • 打赏
  • 举报
回复
谢谢各位指点,我先研究试一下。
m0_37684144 2021-04-28
  • 打赏
  • 举报
回复
TnetHttpClient 对一些证书会出问题,解决不了,最后还是用indyhttp 来解决,提交信息最好模仿浏览器进行提交
sczyq 2021-04-28
  • 打赏
  • 举报
回复
:BlueStorm 是版本的问题, 10.3 THTTPSecureProtocol = (SSL2, SSL3, TLS1, TLS11, TLS12); 我的是 Embarcadero® RAD Studio 10.4 Version 27.0.37889.9797 THTTPSecureProtocol = (SSL2, SSL3, TLS1, TLS11, TLS12, TLS13); 我有个 API 站, 就是 THTTPSecureProtocol.TLS12 的 HTTP.SecureProtocols := [THTTPSecureProtocol.TLS1, THTTPSecureProtocol.TLS11, THTTPSecureProtocol.TLS12]; 或者 HTTP.SecureProtocols := [THTTPSecureProtocol.TLS12]; 都是可以的 看来你要用 10.4 了
BlueStorm 2021-04-28
  • 打赏
  • 举报
回复
BlueStorm 2021-04-28
  • 打赏
  • 举报
回复
引用 15 楼 sczyq 的回复:
[quote=引用 13 楼 BlueStorm 的回复:]delphi xe 10.3.3的TNetHTTPClient的SecureProtocols不支持TLS13.
HTTP.SecureProtocols := [THTTPSecureProtocol.TLS13]; 应该是可以的[/quote] 我用的就是Delphi 10.3.3, 实际测试的结果就是TLS13用不了,而且这个版本Delphi的源代码也不含TLS13字样,请问你是怎么实现TLS13可用的?
sczyq 2021-04-28
  • 打赏
  • 举报
回复
如果: HTTP.ContentType := 'application/json'; 那么参数就用: var PostData : TStringStream; begin ... PostData := TStringStream.Create(Data, TEncoding.UTF8, false); ... end; 其他的都一样
sczyq 2021-04-28
  • 打赏
  • 举报
回复
引用 13 楼 BlueStorm 的回复:
delphi xe 10.3.3的TNetHTTPClient的SecureProtocols不支持TLS13.
HTTP.SecureProtocols := [THTTPSecureProtocol.TLS13]; 应该是可以的
yuzhizhi 2021-04-27
  • 打赏
  • 举报
回复
谢谢大家,我先研究研究。
BlueStorm 2021-04-26
  • 打赏
  • 举报
回复
delphi xe 10.3.3的TNetHTTPClient的SecureProtocols不支持TLS13.
sczyq 2021-04-26
  • 打赏
  • 举报
回复
Memo2.Text:=PostMethod(URL, Data.ToJSON); 或者直接的 Memo2.Text:=PostMethod(URL, '{"Number":"13455216875"}');
sczyq 2021-04-26
  • 打赏
  • 举报
回复
参数名要改成这个: PostData.Values['memV'] = Data;
sczyq 2021-04-26
  • 打赏
  • 举报
回复
为什么不改用 TNetHTTPClient 来做? 做 API 接口当然是首选
uses
	System.NetEncoding, System.Net.HttpClient, System.Net.HttpClientComponent, System.Net.URLClient.hpp;


function TForm1.PostMethod(Url, Data: String): String;
var
  PostData : TStringList;
  HTTP : TNetHTTPClient;
begin
  PostData := TStringList.Create;
	PostData.Values['data'] = Data;
	
  HTTP := TNetHTTPClient.Create(Self);
	HTTP.ConnectionTimeout := 3000;  //  时间设短点
	HTTP.ResponseTimeout := 8000;    //  同上

//	HTTP.ContentType := 'application/x-www-form-urlencoded';

// HTTP.SecureProtocols 需要经过测试,到底应当用那个或者哪些组合, 或者是空的 [] (组件默认)

	HTTP.SecureProtocols := [THTTPSecureProtocol.SSL2];   // SSL2, SSL3, TLS1, TLS11, TLS12, TLS13
  
  try
    try
      Result := HTTP.Post(Url, PostData).ContentAsString(TEncoding.UTF8);
    except
      on e: Exception do
      begin
        AddLog(e.Message);   //这里是写入日志,忽略掉
      end;
    end;
  finally
    FreeAndNil(HTTP);
    FreeAndNil(PostData);
  end;
end;
大肚肥肥 2021-04-21
  • 打赏
  • 举报
回复
建议使用postman 先测试下接口再写代码
tanqth 2021-04-19
  • 打赏
  • 举报
回复
你这个情况,总结来说,是被服务器主动断开连接。可能的情况应该是你没根据他的要求提交数据(包括POST的及HTTP头信息,如ContentType),前面我们一直在检查POST的数据,那么这次可以试试我这个POST的过程。
tanqth 2021-04-19
  • 打赏
  • 举报
回复


const
  //常量定义
  C_NetAdd = 'XXXXXXX.cn/openapi2';

  //SSL
  C_Http = 'http://'; //http定义
  C_Https = 'https://'; //https定义

  //通讯的基础参数
  C_ReadTimeout = 3000; //超时设置 3秒   (根据网络情况设置)
  C_ContentType = 'application/x-www-form-urlencoded'; //数据内容类型  (不可改)
  C_ContentEncoding = 'utf-8'; //数据内容字符集   (不可改)
  C_UserAgent =
    'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)';
  C_AcceptLanguage = 'zh-cn';

var
  V_Ssl :Boolean;//是否使用HTTPS


Function HttpPost(MsgSend: String; vUrl: String): String;
var
  vHttp: TIdHTTP;
  vIdSSL: TIdSSLIOHandlerSocketOpenSSL;
  mStream: TStringStream;
  FUrl: string;
begin
  Result := '';
  if (vUrl <> '') and (MsgSend <> '') then
  begin
    vHttp := TIdHTTP.Create(nil);
    try
      vHttp.ReadTimeout := C_ReadTimeout;
      vHttp.Request.ContentType := C_ContentType;
      vHttp.Request.ContentEncoding := C_ContentEncoding;
      mStream := TStringStream.Create(MsgSend,CP_UTF8);
      if V_Ssl then
      begin
        //使用https安全通讯方式
        vIdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
        vHttp.IOHandler := vIdSSL;
        FUrl := C_Https + vUrl;
      end
      else
      begin
        FUrl := C_Http + vUrl;
      end;
      //Post 数据
      Result := vHttp.Post(FUrl,mStream);

    finally
      vHttp.Disconnect;
      if V_Ssl then
        vIdSSL.Destroy;
      FreeAndNil(vHttp);
      FreeAndNil(mStream);
    end;
  end
  else
    raise Exception.Create('发送信息或Url不能为空');
end;
yuzhizhi 2021-04-19
  • 打赏
  • 举报
回复
我得到还是空对象
BlueStorm 2021-04-19
  • 打赏
  • 举报
回复
引用 5 楼 yuzhizhi 的回复:
我得到还是空对象
那是不可能的事情,你运行一下下面的代码,看看结果是否正常:
procedure TForm1.Button1Click(Sender: TObject);
var
  Data: String;
  PostData: TStringStream;
begin
  Data := '{"Member": "13455216875}';
  PostData := TStringStream.Create(Data, TEncoding.UTF8, False);
  ShowMessage(PostData.DataString);
end;
tanqth 2021-04-13
  • 打赏
  • 举报
回复
你改为:PostData := TStringStream.Create(Data, TEncoding.UTF8, False); 再试试。
BlueStorm 2021-04-13
  • 打赏
  • 举报
回复
yuzhizhi 2021-04-13
  • 打赏
  • 举报
回复
To tanqth: 方法 试过一样的错误。 发现创建的PostData := TStringStream.Create(Data, TEncoding.UTF8, False); 这个为nil To BlueStorm:方法 试过一样的错误。 创建的PostData := TStringStream.Create(Data, TEncoding.UTF8); 这个为nil
加载更多回复(1)
发帖
网络通信/分布式开发

1589

社区成员

Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
帖子事件
创建了帖子
2021-04-12 10:43
社区公告
暂无公告