Delphi调用http服务报错,如下图:
原因分析:
出现这种问题的原因是由于访问的url地址为https或存在其跳转地址为https。单纯使用idhttp是只能访问http,而https则需要搭配IdSSLIOHandlerSocketOpenSSL来实现对https的访问支持,还需要在系统目录或编译目标程序的同目录下有ssleay32.dll与libeay32.dll两个SLL协议的支持库。
解决办法:
注意:此处需要Delphi7+indy10环境,主要逻辑如下,详细请参考代码。
var
SSLIOHandler: TIdSSLIOHandlerSocketOpenSSL;
HTTPClient: TIdHTTP;
begin
SSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
HTTPClient := TIdHTTP.Create(nil);
try
HTTPClient.IOHandler := SSLIOHandler;
//其他代码
finally
HTTPClient.Free;
SSLIOHandler.Free;
end;
end;
参考代码如下:
uses
IdBaseComponent, IdComponent, IdIOHandler,
IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL;
procedure TForm1.btn1Click(Sender: TObject);
var
IdHttp:TIdHTTP;
postUrl: string;
postData: string;
postStream:TStringStream;
returnStream:TMemoryStream;
inf_time: TDateTime;
ret:boolean;
oUrl, oJson,oPaasid, oToken, oNonce,oReturnStr,oEmgs: OleVariant;
sJsonIn,sJsonOut :string;
LStrings: TStringList;
infcode,err_msg:string; //返回值判断交易是否成功
sPath,sDirectory:string;
SSLIO: TIdSSLIOHandlerSocketOpenSSL;
begin
sJsonIn := Memo1.Text;
try
IdHttp:=TIdHTTP.Create(nil);
SSLIO := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
IdHttp.HTTPOptions := IdHttp.HTTPOptions + [hoKeepOrigProtocol]; //必须有这行才使设置协议版本生效
IdHTTP.Request.Accept := 'application/json';
IdHTTP.Request.ContentType := 'application/json';
IdHTTP.Request.ContentEncoding := 'utf-8';
SSLIO.SSLOptions.Method:=sslvTLSv1;
SSLIO.SSLOptions.Mode := sslmClient;
IdHttp.IOHandler := SSLIO;
postUrl := 'https://test.pub.**.com:8089/reg/yyds/mobile/api/amp/hos/getTradeFile';
postData := sJsonIn;
postStream := TStringStream.Create(UTF8Encode(postData));
returnStream := TMemoryStream.Create;
IdHTTP.Post(postUrl, postStream, returnStream);
if returnStream = nil then
begin
ShowMessage('调用接口失败:下载文件失败!');
Exit;
end;
sDirectory := ExtractFilePath(Application.ExeName);
if not DirectoryExists(sDirectory) then
begin
CreateDirectory(PChar(sDirectory), nil);
end;
returnStream.SaveToFile(sDirectory + '\' + '1.ZIP');
finally
IdHttp.Free;
postStream.Free;
returnStream.Free;
FreeAndNil(SSLIO);
end;
except
on e:exception do
begin
showmessage('调用接口异常:'+e.message);
Exit;
end;
end;
end;