尝试连接时 TidHTTP 错误 "A port is needed"

TidHTTP error "A port is needed" when trying to Connect

我正在尝试使用 TIdHTTP 组件连接到安全服务器。我已将 TIdSSLIOHandlerSocketOpenSSL I/O 处理程序分配给 IOHandler 属性,并且我已经下载了 OpenSSL 文件。

当我调用 Connect() 时,它会生成一个 "A port is required" 异常。 Another post 建议 HostPort 应该自动分配给 TIdHTTP。关于我做错了什么有什么建议吗?

如果我不调用 Connect(),站点将返回错误 406,因为连接不安全。

相关代码位是:

try
  IdHttp1.Connect ('https://test-api.service.hmrc.gov.uk');
  IdHttp1.Request.CustomHeaders.AddValue ('Accept', 'application/vnd.hmrc.1.0+json');

  result := IdHTTP1.Get('https://test-api.service.hmrc.gov.uk/hello/world');
except
  on E: Exception do
    memo1.lines.add (E.ClassName + ': ' + E.message);
end;

"Port is required"错误是因为调用Connect()Port属性还没有赋值

但是,与其他 TCP 客户端组件不同的是,在使用 TIdHTTP 时,您根本不应该直接 调用 Connect() 。它的 Get() 方法(和其他请求方法)将在内部为您处理。因此,您需要从代码中删除 Connect() 调用。

HTTP 是一种无状态协议。在对同一服务器的多个请求之间,底层 TCP 连接可能是持久的,也可能是断开的。客户端和服务器在 per-request 的基础上进行协商。 TIdHTTP 通过解析 URL 的主机和端口信息(正如我在您提到的另一个 post 中解释的那样)和 disconnecting/reconnecting TCP 连接来为您处理内部细节需要。

您所要做的就是向 Get()(和其他人)提供有效的 URL,然后让 TIdHTTP 为您管理 TCP 连接。

另外请注意,您不应使用 Request.CustomHeaders 属性 来设置 Accept 请求 header。请改用 Request.Accept 属性。

试试这个:

IdHttp1.Request.Accept := 'application/vnd.hmrc.1.0+json';
try
  Result := IdHTTP1.Get('https://test-api.service.hmrc.gov.uk/hello/world');
except
  on E: Exception do
    Memo1.Lines.Add(E.ClassName + ': ' + E.message);
end;

至于响应代码 406,您收到任何响应都意味着您与服务器建立了有效的 HTTP 连接。但是 406 并不像您声称的那样意味着连接不安全(实际上,它不可能,因为您正在请求 HTTPS url)。 406 实际上意味着服务器无法以您明确要求可接受的格式向您提供响应数据。在这种情况下,无法以您想要的 JSON 格式给出响应。

因此,您需要找出服务器不发送 JSON 的原因并加以解决,或者您需要修改 Accept 请求 header 以包含服务器想改用。

我的 猜测 是服务器可能正在尝试以 non-JSON 格式(可能是 HTML )发回错误消息,所以请尝试暂时删除您的 Accept 请求 header,以便您可以查看实际响应,然后根据需要更新您的请求代码。