Delphi发送HTTP GET请求而无需等待服务器响应

时间:2018-07-09 16:20:29

标签: delphi indy idhttp

我想发送HTTP请求(GET),而不必等待服务器响应。

我尝试通过忽略响应来尝试IdHTTP,例如:

aIdHTTP := TIdHTTP.create;
try
  aIdHTTP.Get('https://stackoverflow.com/');
finally
  aIdHTTP.free;
free

但是它总是等待服务器响应...

一种技巧是通过在TIdHTTP.OnWorkAWorkMode时在wmRead事件中引发异常来关闭连接,这会更快地关闭连接...但是要等待“第一个字节”响应。

有没有一种方法可以发送数据而无需等待响应?

1 个答案:

答案 0 :(得分:10)

最简单的答案是,无论如何都不是TIdHTTP。 HTTP是一个协议,TIdHTTP遵循该协议,其中包括读取服务器的响应。

如您所发现的,您可以TIdHTTP.OnWork事件中引发异常,但这仅在从服务器接收到至少1个字节后才起作用。不过,您可以指定简短的TIdHTTP.ReadTimeout值。

另一种选择是在TIdHTTP.OnHeadersAvailable事件中关闭套接字连接,但这需要TIdHTTP读取服务器的完整响应头。

IF 响应正在使用HTTP 1.1分块,您可以可以hoNoReadChunked属性中启用TIdHTTP.HTTPOptions标志。但这还需要读取服务器的完整响应标头。

确实,完成您所要求的唯一方法是根本不使用TIdHTTP。请改用TIdTCPClient,并手动发送自己的HTTP请求,然后在发送后关闭连接,例如:

aIdClient := TIdTCPClient.Create;
try
  aIdClient.Host := 'stackoverflow.com';
  aIdClient.Port := 443;

  aIdClient.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(aIdClient);
  TIdSSLIOHandlerSocketOpenSSL(aIdClient.IOHandler).PassThrough := False;

  aIdClient.Connect;
  try
    aIdClient.IOHandler.WriteLn('GET / HTTP/1.1');
    aIdClient.IOHandler.WriteLn('Host: stackoverflow.com');
    aIdClient.IOHandler.WriteLn('Connection: close');
    aIdClient.IOHandler.WriteLn;
  finally
    aIdClient.Disconnect;
  end;
finally
  aIdClient.free;
end;

但是请求文件而不实际下载文件有什么意义呢?

如果您只想检查服务器是否可以连接,就不必发送任何内容

aIdClient := TIdTCPClient.Create;
try
  aIdClient.Host := 'stackoverflow.com';
  aIdClient.Port := 443;
  aIdClient.Connect;
  aIdClient.Disconnect;
finally
  aIdClient.free;
end;

如果您只是想避免通过HTTP下载文件的实际内容,则可以使用TIdHTTP.Head()代替TIdHTTP.Get()

aIdHTTP.Head('https://stackoverflow.com/');