IdHttp如何获取响应代码

10

我正在使用idhttp (Indy)进行网站检查。我只想检查发送请求后服务器的响应代码,而不需要实际接收服务器返回的HTML输出,因为我只监视200 OK代码,其他代码都表示存在某种问题。

我查阅了idhttp帮助文档,唯一可能实现这个功能的方法是将代码分配给MemoryStream,然后立即清除它,但这不太高效并且使用了不必要的内存。有没有更有效且不浪费内存的方法来调用站点并获取响应但忽略返回的HTML?

当前的代码大致如下。但这只是样例代码,我还没有测试过,我只是用它来解释我的意图。

Procedure Button1Click(Sender: TObject);

var
http : TIdHttp;
s : TStream;
url : string;
code : integer;

begin 

   s := TStream.Create();
   http := Tidhttp.create();
   url := 'http://www.WEBSITE.com';

   try

    http.get(url,s);
    code := http.ResponseCode;
    ShowMessage(IntToStr(code));

   finally

   s.Free();
   http.Free();

end;
2个回答

16

TIdHTTP.Head()是最佳选项。

不过,在最新版本中,您也可以使用一个空的TStream目标或没有分配事件处理程序的TIdEventStream调用TIdHTTP.Get()TIdHTTP将仍然读取服务器数据但不会在任何地方存储它。

无论哪种方式,还要记住,如果服务器发送回失败响应代码,TIdHTTP将引发异常(除非您使用AIgnoreReplies参数指定您想忽略的特定响应代码值),因此您也应考虑到这一点,例如:

procedure Button1Click(Sender: TObject);
var
  http : TIdHttp;
  url : string;
  code : integer;
begin
  url := 'http://www.WEBSITE.com';
  http := TIdHTTP.Create(nil);
  try
    try
      http.Head(url);
      code := http.ResponseCode;
    except
      on E: EIdHTTPProtocolException do
        code := http.ResponseCode; // or: code := E.ErrorCode;
    end;
    ShowMessage(IntToStr(code));
  finally
    http.Free;
  end;
end; 

procedure Button2Click(Sender: TObject);
var
  http : TIdHttp;
  url : string;
  code : integer;
begin
  url := 'http://www.WEBSITE.com';
  http := TIdHTTP.Create(nil);
  try
    try
      http.Get(url, nil);
      code := http.ResponseCode;
    except
      on E: EIdHTTPProtocolException do
        code := http.ResponseCode; // or: code := E.ErrorCode;
    end;
    ShowMessage(IntToStr(code));
  finally
    http.Free;
  end;
end;

更新:为了避免在失败时引发 EIdHTTPProtocolException,您可以在 TIdHTTP.HTTPOptions 属性中启用 hoNoProtocolErrorException 标志:

procedure Button1Click(Sender: TObject);
var
  http : TIdHttp;
  url : string;
  code : integer;
begin
  url := 'http://www.WEBSITE.com';
  http := TIdHTTP.Create(nil);
  try
    http.HTTPOptions := http.HTTPOptions + [hoNoProtocolErrorException];
    http.Head(url);
    code := http.ResponseCode;
    ShowMessage(IntToStr(code));
  finally
    http.Free;
  end;
end; 

procedure Button2Click(Sender: TObject);
var
  http : TIdHttp;
  url : string;
  code : integer;
begin
  url := 'http://www.WEBSITE.com';
  http := TIdHTTP.Create(nil);
  try
    http.HTTPOptions := http.HTTPOptions + [hoNoProtocolErrorException];
    http.Get(url, nil);
    code := http.ResponseCode;
    ShowMessage(IntToStr(code));
  finally
    http.Free;
  end;
end;

1
我刚刚在玩弄这段代码。所有的操作都在一个线程内运行,但是如果除了200状态码以外出现了404、302等错误或者套接字错误,它会导致线程退出。 - Flatlyn
任何未能成功检索的响应代码都会引发异常。如果您的线程没有处理异常,或者至少没有处理实际引发的特定异常类型,那么是的,线程将退出(并设置'TThread.FatalException'属性)。在我的例子中,它只处理'EIdHTTPProtocolException'异常。根据需要扩展线程代码以处理其他类型的异常。 - Remy Lebeau
如果我们收到一个“继续”(100)的响应,我们需要再尝试一次,对吗? - NaN
TIdHTTP 会为您内部处理 100。不,这不是重试的指示。只有当客户端发送 Expect: 100-Continue 标头时才使用 100,这允许客户端仅发送请求标头,然后等待 100 再发送 POST 正文。这样,如果服务器决定拒绝请求,则不会浪费带宽。 - Remy Lebeau
如果我使用http.Head,一些URL会返回“false” 404错误。更安全的做法是使用http.Get(url,nil)。 - Xel Naga
1
@Andrzej 那些服务器有缺陷,没有正确遵循HTTP规范。 - Remy Lebeau

8

使用http.head()而不是http.get()进行尝试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接