类 Net::HTTPResponse

此类是 Net::HTTP 响应类的基类。

关于示例

此处的示例假设已要求 net/http(这也要求 uri

require 'net/http'

此处的许多代码示例使用以下示例网站

一些示例还假设以下变量

uri = URI('https://jsonplaceholder.typicode.com/')
uri.freeze # Examples may not modify.
hostname = uri.hostname # => "jsonplaceholder.typicode.com"
path = uri.path         # => "/"
port = uri.port         # => 443

这样,示例请求就可以写成

Net::HTTP.get(uri)
Net::HTTP.get(hostname, '/index.html')
Net::HTTP.start(hostname) do |http|
  http.get('/todos/1')
  http.get('/todos/2')
end

需要修改的示例 URI 首先复制 uri,然后修改副本

_uri = uri.dup
_uri.path = '/todos/1'

返回的响应

方法 Net::HTTP.get_response 返回 Net::HTTPResponse 子类的实例之一

Net::HTTP.get_response(uri)
# => #<Net::HTTPOK 200 OK readbody=true>
Net::HTTP.get_response(hostname, '/nosuch')
# => #<Net::HTTPNotFound 404 Not Found readbody=true>

方法 Net::HTTP#request 也是如此

req = Net::HTTP::Get.new(uri)
Net::HTTP.start(hostname) do |http|
  http.request(req)
end # => #<Net::HTTPOK 200 OK readbody=true>

类 Net::HTTPResponse 包含模块 Net::HTTPHeader,它通过(除其他外)提供对响应标头值的访问

示例

res = Net::HTTP.get_response(uri) # => #<Net::HTTPOK 200 OK readbody=true>
res['Content-Type']               # => "text/html; charset=UTF-8"
res.content_type                  # => "text/html"

响应子类

类 Net::HTTPResponse 针对每个 HTTP 状态代码 都有一个子类。您可以查找给定代码的响应类

Net::HTTPResponse::CODE_TO_OBJ['200'] # => Net::HTTPOK
Net::HTTPResponse::CODE_TO_OBJ['400'] # => Net::HTTPBadRequest
Net::HTTPResponse::CODE_TO_OBJ['404'] # => Net::HTTPNotFound

您可以检索响应对象的代码

Net::HTTP.get_response(uri).code                 # => "200"
Net::HTTP.get_response(hostname, '/nosuch').code # => "404"

响应子类(缩进显示类层次结构)

此外,当出现协议错误时,还会引发 Net::HTTPBadResponse 异常。

常量

CODE_CLASS_TO_OBJ
CODE_TO_OBJ

属性

body_encoding[R]

返回由 body_encoding= 设置的值,如果未设置则返回 false;请参阅 body_encoding=.

code[R]

HTTP 结果代码字符串。例如,‘302’。您还可以通过检查响应对象是哪个响应子类的实例来确定响应类型。

decode_content[RW]

Set 在请求中没有包含来自用户的 Accept-Encoding 头部时,会自动设置为 true。

http_version[R]

服务器支持的 HTTP 版本。

ignore_eof[RW]

是否在读取带有指定 Content-Length 头部的正文时忽略 EOF。

message[R]

服务器发送的 HTTP 结果消息。例如,‘Not Found’。

msg[R]

服务器发送的 HTTP 结果消息。例如,‘Not Found’。

uri[R]

用于获取此响应的 URI。只有在使用 URI 创建请求时,响应 URI 才可用。

公共类方法

body_permitted?() 点击切换源代码

如果响应有正文,则为 true。

# File lib/net/http/response.rb, line 138
def body_permitted?
  self::HAS_BODY
end

私有类方法

each_response_header(sock) { |key, value| ... } 点击切换源代码
# File lib/net/http/response.rb, line 170
def each_response_header(sock)
  key = value = nil
  while true
    line = sock.readuntil("\n", true).sub(/\s+\z/, '')
    break if line.empty?
    if line[0] == ?\s or line[0] == ?\t and value
      value << ' ' unless value.empty?
      value << line.strip
    else
      yield key, value if key
      key, value = line.strip.split(/\s*:\s*/, 2)
      raise Net::HTTPBadResponse, 'wrong header line format' if value.nil?
    end
  end
  yield key, value if key
end
read_status_line(sock) 点击切换源代码
# File lib/net/http/response.rb, line 157
def read_status_line(sock)
  str = sock.readline
  m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)(?:\s+(.*))?\z/in.match(str) or
    raise Net::HTTPBadResponse, "wrong status line: #{str.dump}"
  m.captures
end
response_class(code) 点击切换源代码
# File lib/net/http/response.rb, line 164
def response_class(code)
  CODE_TO_OBJ[code] or
  CODE_CLASS_TO_OBJ[code[0,1]] or
  Net::HTTPUnknownResponse
end

公共实例方法

body() 点击切换源代码

返回字符串响应正文;请注意,对未修改的正文的重复调用将返回一个缓存的字符串

path = '/todos/1'
Net::HTTP.start(hostname) do |http|
  res = http.get(path)
  p res.body
  p http.head(path).body # No body.
end

输出

"{\n  \"userId\": 1,\n  \"id\": 1,\n  \"title\": \"delectus aut autem\",\n  \"completed\": false\n}"
nil
# File lib/net/http/response.rb, line 400
def body
  read_body()
end
也称为:entity
body=(value) 点击切换源代码

将响应的正文设置为给定值。

# File lib/net/http/response.rb, line 405
def body=(value)
  @body = value
end
body_encoding=(value) 点击切换源代码

设置读取正文时应使用的编码

  • 如果给定值为 Encoding 对象,则将使用该编码。

  • 否则,如果值为字符串,则将使用 Encoding#find(value) 的值。

  • 否则,将从正文本身推断出编码。

示例

http = Net::HTTP.new(hostname)
req = Net::HTTP::Get.new('/')

http.request(req) do |res|
  p res.body.encoding # => #<Encoding:ASCII-8BIT>
end

http.request(req) do |res|
  res.body_encoding = "UTF-8"
  p res.body.encoding # => #<Encoding:UTF-8>
end
# File lib/net/http/response.rb, line 253
def body_encoding=(value)
  value = Encoding.find(value) if value.is_a?(String)
  @body_encoding = value
end
entity()
别名:body
inspect() 点击切换源代码
# File lib/net/http/response.rb, line 262
def inspect
  "#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
end
read_body(dest = nil, &block) 点击切换源代码

获取远程 HTTP 服务器返回的实体主体。

如果提供了代码块,则主体将传递给代码块,并且主体将以片段形式提供,因为它从套接字中读取。

如果提供了 dest 参数,则响应将读取到该变量中,使用 dest#<< 方法(它可以是 StringIO,或任何其他响应 << 的对象)。

对同一个 HTTPResponse 对象第二次或后续调用此方法将返回已读取的值。

http.request_get('/index.html') {|res|
  puts res.read_body
}

http.request_get('/index.html') {|res|
  p res.read_body.object_id   # 538149362
  p res.read_body.object_id   # 538149362
}

# using iterator
http.request_get('/index.html') {|res|
  res.read_body do |segment|
    print segment
  end
}
# File lib/net/http/response.rb, line 355
def read_body(dest = nil, &block)
  if @read
    raise IOError, "#{self.class}\#read_body called twice" if dest or block
    return @body
  end
  to = procdest(dest, block)
  stream_check
  if @body_exist
    read_body_0 to
    @body = to
  else
    @body = nil
  end
  @read = true
  return if @body.nil?

  case enc = @body_encoding
  when Encoding, false, nil
    # Encoding: force given encoding
    # false/nil: do not force encoding
  else
    # other value: detect encoding from body
    enc = detect_encoding(@body)
  end

  @body.force_encoding(enc) if enc

  @body
end
value() 点击切换源代码

如果响应不是 2xx(成功),则引发 HTTP 错误。

# File lib/net/http/response.rb, line 285
def value
  error! unless self.kind_of?(Net::HTTPSuccess)
end