11

在 Delphi 中,我使用 Indy'sTIdHTTPWebBrokerBridge加上TIdHTTP通过 HTTP 发送/接收数据。在服务器上,我没有任何花哨的处理,我总是只用一个简单的内容流来响应。如果有任何问题,我只会在响应内容中返回有关该问题的信息(例如身份验证失败、无效请求等)。那么,在客户端,我是否可以假设我向该服务器发出的每个成功请求都将始终具有 200(OK)的响应代码?

我想知道,因为在客户端,请求被包装在函数中,这些函数只返回一个布尔值来表示请求是否成功。

在这个函数里面:

IdHTTP.Get(SomeURL, AStream);
Result:= IdHTTP.ResponseCode = 200;

这个函数处理所有可能获取数据的请求。如果请求中有任何问题,此函数应返回 False。在我的场景中,由于我总是在服务器上返回某种内容,客户端会在这个函数中总是收到 200 的响应代码吗?

我想真正的问题是,如果我总是返回某种内容并处理服务器上的所有异常,那么服务器是否总是向每个请求返回状态码 200?

4

4 回答 4

17

“每个成功的 HTTP 请求是否总是返回状态码 200?”

w3.org: HTTP/1.1 Status Code Definitions( RFC 2616)

答案是否定的。所有 2xx 都被认为是成功的。这可能取决于使用的HTTP 方法

您的Web 服务器应用程序是否应该在成功时始终返回 200?这也可能取决于请求方法和它为客户端准备的信号。例如

对于PUT方法(重点是我的):

如果修改了现有资源,则应发送200(OK)或204(No Content)响应代码以指示请求成功完成。

对于POST方法:

POST 方法执行的操作可能不会产生可由 URI 标识的资源。在这种情况下,200(正常)或204 (无内容)是适当的响应状态,具体取决于响应是否包含描述结果的实体。

如果在源服务器上创建了资源,则响应 应该201(已创建)并包含描述请求状态并引用新资源的实体和 Location 标头(参见第 14.30 节)。对此方法的响应是不可缓存的,除非响应包含适当的 Cache-Control 或 Expires 标头字段。但是,303(请参阅其他)响应可用于指示用户代理检索可缓存资源。

正如您可以从 中了解到的RCF,每个方法都应该有自己的成功状态代码,具体取决于实现。

你的另一个问题:

“我可以假设我向该服务器发出的每个成功请求都将始终具有 200(OK)的响应代码吗?”

如果您的Web 服务器始终以状态 200 响应,则您始终可以期待状态代码200。您的 Web 服务器应用程序控制它返回给客户端的响应。

也就是说,状态码 200 是成功 HTTP 请求的标准响应(实际响应将取决于所使用的请求方法),在 Web 服务器的现实世界中,除非另有说明,否则应该在成功请求时将其设置为默认值(如在雷米的回答中解释)。

于 2013-02-28T21:20:54.583 回答
9

要回答您的具体问题:

我可以假设我向该服务器发出的每个成功请求都将始终具有 200(OK)的响应代码吗?

答案是Yes,因为TIdHTTPWebBrokerBridgewrapsTIdHTTPServer总是将每个请求的默认响应代码设置为 200 ,除非您自己用不同的值覆盖它,或者让您的服务器执行一些隐式回复不同响应代码的操作(例如Redirect()使用 302 ,或者SmartServeFile()使用 304),或者遇到导致TIdHTTPServer分配 4xx 或 5xx 错误响应代码的错误。

然而,总的来说,其他人告诉你的都是真的。在客户端,您应该处理任何可能的 HTTP 成功响应代码,而不仅仅是 200 本身。不要对服务器实现做任何假设。

事实上,TIdHTTP已经为您处理好了。如果TIdHTTP遇到它认为是错误代码的响应代码,它将EIdHTTPProtocolException在您的代码中引发异常。因此,如果您没有收到异常,则假设响应成功。您无需手动检查响应代码。

如果有一个特定的响应代码通常会引发异常但您不希望它发生,您可以在or的可选AIgnoreReplies参数中指定该值。或者,如果您使用的是最新的 Indy 10 SVN 修订版,则最近向属性添加了一个新标志,因此不会针对任何响应代码引发异常。TIdHTTP.Get()TIdHTTP.DoRequest()hoNoProtocolErrorExceptionTIdHTTP.HTTPOptionsEIdHTTPProtocolException

于 2013-02-28T22:21:15.583 回答
2

成功的响应是 2xx List_of_HTTP_status_codes

于 2013-02-28T20:42:51.567 回答
1

我做了以下。直接处理所有 200 和 LOG 异常。工作,没有一个非 200 - 除了未经授权和超时(密码或有时不可用的服务器)。但是对于广泛的主流应用程序,将考虑许多/所有响应。

      while (iRedo < 3) do begin
        s := Self.HTTPComponent.Get( sUrl );

        if self.HTTPComponent.ResponseCode = 200 then begin
          break;
        end;

        // IDEIA - log what happend if not 200
        logWhatHappend( s, HTTPComponent ); // then log content, headers, etc
        inc( iRedo ); sleep( 5 );
      end;
于 2015-10-04T15:50:14.390 回答