我正试图使用TIdHTTP
组件连接到安全服务器。我已经为IOHandler
属性分配了一个TIdSSLIOHandlerSocketOpenSSL
I/O处理程序,并下载了OpenSSL文件。
当我调用Connect()
时,它会生成一个"A port is required"异常。另一篇文章建议Host
和Port
应该自动分配给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连接可能是持久的,也可能是断开的。客户端和服务器根据每个请求进行协商。TIdHTTP
通过解析主机和端口信息的URL(正如我在您提到的另一篇文章中所解释的),并根据需要断开/重新连接TCP连接,在内部为您处理这些细节。
您所要做的就是向Get()
(和其他人)提供一个有效的URL,并让TIdHTTP
为您管理TCP连接。
另外,您不应该使用Request.CustomHeaders
属性来设置Accept
请求标头。请改用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
请求标头,以包含服务器想要使用的格式。
我的猜测是服务器可能试图以非JSON格式(可能是HTML格式)发回错误消息,所以请尝试暂时删除Accept
请求标头,以便查看实际响应,然后根据需要更新请求代码。