【问题标题】:How to get images from HTTPS URL in Delphi?如何从 Delphi 中的 HTTPS URL 获取图像?
【发布时间】:2020-01-18 05:04:07
【问题描述】:

我正在尝试从 URL 开始加载 TImage,如 this answer 中所述。

uses
  GIFImg;

procedure TForm1.Button1Click(Sender: TObject);
var
  Stream : TMemoryStream;
  GIF : TGIFImage;
begin
  Stream := TMemoryStream.Create;
  GIF := TGIFImage.Create;
  try
    IdHTTP1.Get('http://www.google.com/intl/en_ALL/images/logo.gif', Stream);
    //IdHTTP1.Get('https://www.google.com/intl/en_ALL/images/logo.gif', Stream);

    Stream.Position := 0;
    GIF.LoadFromStream(Stream);

    Image1.Picture.Assign(GIF);

  finally
    FreeAndNil(GIF);
    FreeAndNil(Stream);
  end;
end;

如果 URL 以简单的 HTTP 开头,则一切正常。

当我尝试从 HTTPS URL 加载时,我收到 EIdIOHandlerPropInvalid 异常消息:

IOHandler 值无效。

我尝试添加一个TIdSSLIOHandlerSocketOpenSSL 并将其设置为IOHandler 用于TIdHTTP 组件。

这样做之后,我收到一个 EIdOSSLCouldNotLoadSSLLibrary 异常,并显示以下消息:

无法加载 SSL 库。

是属性有问题还是有其他问题?

【问题讨论】:

    标签: delphi indy delphi-2007


    【解决方案1】:

    当我尝试从 HTTPS URL 加载时,我收到 EIdIOHandlerPropInvalid 异常消息:

    IOHandler 值无效。

    该错误意味着您没有将TIdSSLIOHandlerSocketBase 派生组件附加到TIdHTTP.IOHandler 属性,例如TIdSSLIOHandlerSocketOpenSSL

    此错误还告诉我您使用的是过时版本的 Indy,需要升级。 TIdHTTP 在请求 HTTPS url 时会自动创建一个默认的 SSLIOHandler 并且当前没有分配 IOHandlerhas done so for a long time

    我尝试为TIdHTTP 组件添加TIdSSLIOHandlerSocketOpenSSL 并将其设置为IOHandler

    这是正确的解决方案,如果您不想升级,或者如果您需要自定义 SSLIOHandler 设置,例如启用 TLS 1.1+(TIdSSLIOHandlerSocketOpenSSLdoes not do by default yet)。

    执行此操作后,我收到 EIdOSSLCouldNotLoadSSLLibrary 异常并显示以下消息:

    无法加载 SSL 库。

    那个错误意味着要么

    • 您尚未在您的应用中部署 OpenSSL DLL(libeay32.dllssleay32.dll),或者至少将它们安装在系统的 DLL search path 的某个位置。

    • 您使用的 DLL 版本与您的 Indy 版本不兼容。当前版本的 Indy 支持 OpenSSL 1.0.2 及更早版本(对 OpenSSL 1.1.x 的支持为 currently a work in progress)。

    报错后,可以在IdSSLOpenSSLHeaders单元中使用Indy的WhichFailedToLoad()函数来判断失败的根本原因——DLL本身是否无法加载到内存中(因为找不到等),或者因为它们缺少 Indy 需要的特定导出。

    【讨论】:

    • 我的应用程序是 32 位的,我已将从 openssl-1.0.2q-i386-win32.zip 下载的 libeay32.dllssleay32.dll 放在可执行文件夹中this page。报错后WhichFailedToLoad函数结果:SSL_CTX_set_info_callback_indy X509_STORE_CTX_get_app_data_indy X509_get_notBefore_indy X509_get_notAfter_indy SSL_SESSION_get_id_indy SSL_SESSION_get_id_ctx_indy SSL_CTX_get_version_indy SSL_CTX_set_options_indy des_set_odd_parity des_set_key des_ecb_encrypt
    • 我怀疑这些 DLL 与我的 Indy 版本不兼容。我使用的是 Delphi-2007 附带的 Indy 版本,在我的设计安装包中,我可以看到“Indy 10 Core Design Time”和“Indy 10 Protocols Design Time”。我如何知道哪个是适合我的 Indy 版本的 OpenSSL 版本?
    • 我已经从indy_openssl096k.zipthis page 下载了这两个 DLL。在此之后,错误现在是 EIdOSSLConnectError,并带有消息“与 SSL 连接时出错。” WhichFailedToLoad() 产生一个空字符串。
    • @Fabrizio 您使用的是极旧版本的 Indy。 Indy 多年前就停止使用..._indy DLL 函数。它们是添加到早期版本的 OpenSSL 源代码中的自定义函数,用于访问 Indy 的内部数据,标准 API 已在更高版本的 OpenSSL 中添加。您需要升级您的 Indy 版本才能使用官方 OpenSSL DLL。 Indy的current version是10.6.2.5517,它支持的OpenSSL最新版本是1.0.2t。 ..._indy 函数不存在于任何超过 0.9.6k 的 OpenSSL DLL 中
    【解决方案2】:

    您需要将 SSL 库(两个 .DLL 文件)安装在您的 Windows 中,或者与您的应用程序一起分发。

    似乎可以在这里下载:

    https://slproweb.com/products/Win32OpenSSL.html

    或者通过他们的官方网站(但我在那里找不到可下载的二进制文件 - 只有源代码):

    https://www.openssl.org/source/

    可在此处下载用于 Indy 的预编译 .DLL:

    https://indy.fulgan.com/SSL/(谢谢,Zed)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 2019-05-02
      相关资源
      最近更新 更多