【问题标题】:Check Ruby HTTP response for success检查 Ruby HTTP 响应是否成功
【发布时间】:2012-08-14 22:21:26
【问题描述】:

如何正确检查来自 Net::HTTP::Get(例如)的响应是否“成功”(即 2xx 返回码)?可悲的是,文档似乎对这个简单的问题保持沉默。

我有:

response=Net::HTTP.new( host, port ).request my_get_request # details not important

经过一堆谷歌搜索和近乎随机的输入,我终于确定这是可行的:

response.class < Net::HTTPSuccess

这实际上是规范的做法吗?

【问题讨论】:

    标签: ruby net-http


    【解决方案1】:

    对于Net::HTTP,是的,检查响应对象的类是这样做的方法。使用kind_of?(别名为is_a?)会更清晰一些(但在功能上等同于使用&lt;):

    response.kind_of? Net::HTTPSuccess
    

    如果状态码不成功,在response 上调用value 也会引发Net::HTTPError(多么糟糕的方法......)。

    如果可以,您可能需要考虑使用 gem 而不是 Net::HTTP,因为它们通常提供更好的 API 和性能。 TyphoeusHTTParty 是两个不错的,among others

    【讨论】:

    • 谢谢!在任何地方都找不到一个示例。
    • 这是针对任何响应 2xx 还是 3xx?在上面找不到任何文档。
    • @Maarten 3xx 不是 HTTP 中定义的成功响应,Net::HTTP 遵守这一点。 3xx 的类型为Net::HTTPRedirection
    • 那么我想任何使用它的人都应该知道服务器可能会返回304 Not Modified,因此可能还想检查Net::HTTPRedirection的情况!
    • 这段代码读起来很有趣。 “回应有点成功?不,不是真的。不过,这部分很好”。 :)
    【解决方案2】:

    您可以利用 Ruby 的 case 语句,该语句惯用地执行类比较,这要归功于它在后台使用了 ===

    这是一个来自 JSON 客户端的示例,它捕获特定错误,但仅返回服务器的消息:

      case response
        when Net::HTTPSuccess
          JSON.parse response.body
        when Net::HTTPUnauthorized
          {'error' => "#{response.message}: username and password set and correct?"}
        when Net::HTTPServerError
          {'error' => "#{response.message}: try again later?"}
        else
          {'error' => response.message}
      end
    

    上面的注释Net::HTTPResponse parent classes(例如Net::HTTPServerError)也可以。

    【讨论】:

      【解决方案3】:

      如果您只想获取外部 API 或网站的 HTTP 状态代码,请尝试Net::HTTP.get_response

      Net::HTTP.get(url) 返回一个字符串。您将无法轻松地从中解析标头响应:

      url = URI('http://example.com')
      string_response = Net::HTTP.get(url)
      # => "<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.</p>\n    <p><a href=\"http://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n"
      
      string_response.class
      # => String
      string_response.kind_of? Net::HTTPSuccess
      # => false
      
      status_response = Net::HTTP.get_response(url)
      # => #<Net::HTTPOK 200 OK readbody=true>
      status_response.class
      # => Net::HTTPOK
      status_response.kind_of? Net::HTTPSuccess
      # => true
      

      【讨论】:

        猜你喜欢
        • 2015-07-25
        • 1970-01-01
        • 2015-01-06
        • 2013-10-25
        • 1970-01-01
        • 2021-01-28
        • 1970-01-01
        • 1970-01-01
        • 2011-05-25
        相关资源
        最近更新 更多