首页 > 解决方案 > Delphi 发送 HTTP GET 请求而不等待服务器响应

问题描述

我想在不等待服务器响应的情况下发送 HTTP 请求(GET)。

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

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

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

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

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

标签: delphiindyidhttp

解决方案


简短的回答是NOTIdHTTP,无论如何都不是 with 。HTTP 是一种协议,它TIdHTTP遵循协议,包括读取服务器的响应。

正如您所发现的,您可以在事件中引发异常TIdHTTP.OnWork,但这仅在从服务器接收到至少 1 个字节时才会起作用。不过,您可以指定一个短TIdHTTP.ReadTimeout值来避免这种情况。

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

如果响应使用 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/');

推荐阅读