我想知道如何在Delphi中使用协议https://下载文件。我正在使用idhttp,但是当我点击下载时会返回错误代码:
series = pd.Series()
for l in b_list:
series.append(l.get_results())
print(l.get_results())
count += 1
print(series)
单击按钮后,几秒钟就会终止应用程序。
-1
答案 0 :(得分:5)
首先,您的错误处理是错误的。您只显示TIdHTTP.ResponseCode
属性值,而不显示任何其他值。 ResponseCode
具有有意义值的唯一例外是EIdHTTPProtocolException
(即使这样,您也应该从EIdHTTPProtocolException.ErrorCode
属性获取值)。 ResponseCode
不太可能在任何其他例外中填充,在您的情况下显然就是这种情况。由于您将遇到捕获不同类型异常的麻烦,您应该显示对这些特定类型有意义的错误消息,例如:
except
on E: EIdHTTPProtocolException do begin
ShowMessage('HTTP request failed'#13 + IntToStr(E.ErrorCode) + ' ' + E.Message);
end;
on E: EIdOpenSSLAPISSLError do
begin
ShowMessage('OpenSSL API failure'#13 + E.ClassName + #13'Result Code: ' + IntToStr(E.RetCode) + #13'Error Code: ' + IntToStr(E.ErrorCode));
end;
on E: EIdOpenSSLAPICryptoError do
begin
ShowMessage('OpenSSL crypto failure'#13 + E.ClassName + #13'Error Code: ' + IntToStr(E.ErrorCode));
end;
on E: EIdOpenSSLError do
begin
ShowMessage('Unknown OpenSSL error'#13 + E.ClassName + #13 + E.Message);
end;
on E: EIdSocketError do begin
ShowMessage('Socket error'#13 + E.ClassName + #13'Error Code: ' + IntToStr(E.LastError) + ' ' + E.Message);
end;
on E: Exception do begin
ShowMessage('Unexpected error'#13 + E.ClassName + #13 + E.Message);
end;
end;
其次,如果您在桌面系统(Windows或OSX)上运行应用程序,则会泄漏TIdSSLIOHandlerSocketOpenSSL
对象,因为您没有为其分配Owner
,{{1不承担它的所有权。如果您在移动系统上运行应用程序(iOS或Android),则代码将崩溃,因为没有引用在创建TIdHTTP
对象后保持活动状态。 TIdSSLIOHandlerSocketOpenSSL
和TIdTCPConnection.IOHandler
属性在这些平台上使用 weak 引用,因此对象的引用计数不会增加,并且最终会被过早销毁。如果您未指定TIdTCPConnection.Socket
,则需要明确释放该对象,例如在Zam的答案演示的Owner
中。
或者,如果您使用的是Indy的最新版本,则可以利用今年早些时候添加到try/finally
的新HTTPS功能,这样您就不必创建{ {1}}显式对象:
New HTTPS functionality for TIdHTTP
第三,关于你得到的实际例外,TIdHTTP
正是它的名字所暗示的。无法加载OpenSSL库。这意味着无法找到DLL(libeay32.dll和ssleay32.dll),或者它们不会导出Indy查找的所有内容。您可以调用IOHandler
单元中的EIdOSSLCouldNotLoadSSLLibrary
函数来找出无法加载OpenSSL的原因:
WhichFailedToLoad()
确保安装了OpenSSL DLL的兼容版本,无论是在应用程序的文件夹中,在OS搜索路径上的文件夹中,还是在通过其IdSSLOpenSSLHeaders
功能指定给Indy的文件夹中。 except
//...
on E: EIdOSSLCouldNotLoadSSLLibrary do
begin
ShowMessage('Could not load OpenSSL library'#13'Failed to load: ' + WhichFailedToLoad);
end;
//...
end;
单位。通常,您应该努力始终使用可用的最新OpenSSL版本(在撰写本文时,它是1.0.2d)。
答案 1 :(得分:2)
首先,您没有使用所有必需的单位。
uses
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL;
这是工作样本,在Delphi XE7和XE8下测试。 FMX平台。
var
FResponse: TMemoryStream;
procedure Load;
var
LUrl: String;
IdHTTP: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
LUrl := 'https://google.lv/';
IdHTTP := TIdHTTP.Create(nil);
try
IdSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
IdHTTP.IOHandler := IdSSLIOHandlerSocketOpenSSL;
try
IdHTTP.Get(LUrl, FResponse);
except
{ We are hiding error }
end;
finally
IdSSLIOHandlerSocketOpenSSL.Free;
end;
finally
IdHTTP.Free;
end;
end;
不要忘记使用FResponse := TMemoryStream.Create;
和last:确保使用正确的OpenSSL库 对于我正在使用的Indy 10.6.1.5182:
[WIN] [x86] OpenSSL共享库1.0.1.7; OpenSSL Toolkit 1.0.1g;
libeay32.dll
1 281 024 bytes
ssleay32.dll
270 336 bytes
[WIN] [x64] OpenSSL共享库1.0.1.7; OpenSSL Toolkit 1.0.1g;
libeay32.dll
1 817 088 bytes
ssleay32.dll
371 200 bytes