【问题标题】:IdHttp Just Get Response CodeIdHttp 获取响应码
【发布时间】:2011-06-25 03:04:57
【问题描述】:

我正在使用 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;

【问题讨论】:

    标签: delphi indy idhttp


    【解决方案1】:

    TIdHTTP.Head() 是最好的选择。

    但是,作为替代方案,在最新版本中,您可以使用 nil 目标 TStreamTIdEventStream 调用 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;
    

    【讨论】:

    • 我一直在玩这个代码。所有这些都在一个线程内运行,但是如果除了 200 代码回复之外还有任何其他内容,例如404、302等或套接字错误导致线程退出。
    • 任何不表示成功检索的响应代码都会引发异常。如果您的线程没有处理异常,或者至少没有处理实际引发的特定异常类型,那么是的,线程将退出(并且将设置 TThread.FatalException 属性)。在我的示例中,它仅处理 EIdHTTPProtocolException 异常。如果需要,扩展您的线程代码以处理其他类型的异常。
    • @RemyLebeau 如果我们收到“继续”100 响应怎么办?我们需要再试一次,对吧?
    • TIdHTTP 在内部为您处理 100。不,这不是重试的迹象。 100 仅在客户端发送 Expect: 100-Continue 标头时使用,它允许客户端仅发送请求标头,然后在发送 POST 正文之前等待 100。这样,如果服务器决定拒绝请求,就不会浪费带宽。
    • @Andrzej 那么这些服务器有缺陷并且没有正确遵循 HTTP 规范。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-04
      • 2016-04-06
      相关资源
      最近更新 更多