当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Ruby HTTP类用法及代码示例


本文简要介绍ruby语言中 Net::HTTP类 的用法。

用于 Ruby 的 HTTP 客户端 API。

Net::HTTP 提供了一个丰富的库,可用于构建 HTTP user-agents。有关 HTTP 的更多详细信息,请参阅 [RFC2616](www.ietf.org/rfc/rfc2616.txt)。

Net::HTTP 旨在与 URI 密切合作。 URI::HTTP#host URI::HTTP#port URI::HTTP#request_uri 旨在与 Net::HTTP 一起使用。

如果您只执行几个 GET 请求,您应该尝试 OpenURI

简单的例子

所有示例都假定您已加载 Net::HTTP

require 'net/http'

这也将需要‘uri’,因此您不需要单独要求它。

以下部分中的 Net::HTTP 方法不会保持连接。如果您执行许多 HTTP 请求,则不建议使用它们。

GET

Net::HTTP.get('example.com', '/index.html') # => String

通过 URI 获取

uri = URI('http://example.com/index.html?count=10')
Net::HTTP.get(uri) # => String

带有动态参数的 GET

uri = URI('http://example.com/index.html')
params = { :limit => 10, :page => 3 }
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
puts res.body if res.is_a?(Net::HTTPSuccess)

POST

uri = URI('http://www.example.com/search.cgi')
res = Net::HTTP.post_form(uri, 'q' => 'ruby', 'max' => '50')
puts res.body

具有多个值的 POST

uri = URI('http://www.example.com/search.cgi')
res = Net::HTTP.post_form(uri, 'q' => ['ruby', 'perl'], 'max' => '50')
puts res.body

如何使用 Net::HTTP

以下示例代码可用作 HTTP user-agent 的基础,它可以使用持久连接执行各种请求类型。

uri = URI('http://example.com/some_path?query=string')

Net::HTTP.start(uri.host, uri.port) do |http|
  request = Net::HTTP::Get.new uri

  response = http.request request # Net::HTTPResponse object
end

Net::HTTP::start 立即创建到 HTTP 服务器的连接,该服务器在块期间保持打开状态。如果服务器指示它支持持久连接,则该连接将对块中的多个请求保持打开状态。

如果您希望在多个 HTTP 请求之间重复使用连接而不自动关闭它,您可以使用 ::new ,然后手动调用 start finish

Net::HTTP 支持的请求类型在下面的 “HTTP Request Classes” 部分中列出。

对于所有 Net::HTTP 请求对象和快捷方式请求方法,您可以为请求路径提供 String URI Net::HTTP 将从中提取请求路径。

响应数据

uri = URI('http://example.com/index.html')
res = Net::HTTP.get_response(uri)

# Headers
res['Set-Cookie']            # => String
res.get_fields('set-cookie') # => Array
res.to_hash['set-cookie']    # => Array
puts "Headers: #{res.to_hash.inspect}"

# Status
puts res.code       # => '200'
puts res.message    # => 'OK'
puts res.class.name # => 'HTTPOK'

# Body
puts res.body if res.response_body_permitted?

跟随重定向

每个 Net::HTTPResponse 对象都属于其响应代码的一个类。

例如,所有 2XX 响应都是 Net::HTTPSuccess 子类的实例,3XX 响应是 Net::HTTPRedirection 子类的实例,而 200 响应是 Net::HTTPOK 类的实例。有关响应类的详细信息,请参阅下面的 “HTTP Response Classes” 部分。

使用 case 语句,您可以正确处理各种类型的响应:

def fetch(uri_str, limit = 10)
  # You should choose a better exception.
  raise ArgumentError, 'too many HTTP redirects' if limit == 0

  response = Net::HTTP.get_response(URI(uri_str))

  case response
  when Net::HTTPSuccess then
    response
  when Net::HTTPRedirection then
    location = response['location']
    warn "redirected to #{location}"
    fetch(location, limit - 1)
  else
    response.value
  end
end

print fetch('http://www.ruby-lang.org')

POST

可以使用 Net::HTTP::Post 请求类进行 POST。此示例创建一个 URL 编码的 POST 正文:

uri = URI('http://www.example.com/todo.cgi')
req = Net::HTTP::Post.new(uri)
req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')

res = Net::HTTP.start(uri.hostname, uri.port) do |http|
  http.request(req)
end

case res
when Net::HTTPSuccess, Net::HTTPRedirection
  # OK
else
  res.value
end

要发送 multipart/form-data 使用 Net::HTTPHeader#set_form

req = Net::HTTP::Post.new(uri)
req.set_form([['upload', File.open('foo.bar')]], 'multipart/form-data')

可以使用相应的请求类 ( Net::HTTP::Put ) 以相同的方式创建可以包含 PUT 等主体的其他请求。

设置标题

以下示例使用 If-Modified-Since 标头执行条件 GET。如果文件自标头中的时间以来没有被修改,则将返回 Not Modified 响应。有关详细信息,请参阅 RFC 2616 第 9.3 节。

uri = URI('http://example.com/cached_response')
file = File.stat 'cached_response'

req = Net::HTTP::Get.new(uri)
req['If-Modified-Since'] = file.mtime.rfc2822

res = Net::HTTP.start(uri.hostname, uri.port) {|http|
  http.request(req)
}

open 'cached_response', 'w' do |io|
  io.write res.body
end if res.is_a?(Net::HTTPSuccess)

基本认证

基本身份验证根据 [RFC2617](www.ietf.org/rfc/rfc2617.txt) 执行。

uri = URI('http://example.com/index.html?key=value')

req = Net::HTTP::Get.new(uri)
req.basic_auth 'user', 'pass'

res = Net::HTTP.start(uri.hostname, uri.port) {|http|
  http.request(req)
}
puts res.body

流式响应机构

默认情况下, Net::HTTP 将整个响应读入内存。如果您正在处理大文件或希望实现进度条,则可以将正文直接流式传输到 IO

uri = URI('http://example.com/large_file')

Net::HTTP.start(uri.host, uri.port) do |http|
  request = Net::HTTP::Get.new uri

  http.request request do |response|
    open 'large_file', 'w' do |io|
      response.read_body do |chunk|
        io.write chunk
      end
    end
  end
end

HTTPS

Net::HTTP#use_ssl= HTTP 连接启用了 HTTPS。

uri = URI('https://secure.example.com/some_path?query=string')

Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
  request = Net::HTTP::Get.new uri
  response = http.request request # Net::HTTPResponse object
end

或者,如果您只是想发出 GET 请求,您可以传入一个具有 HTTPS URL 的 URI 对象。如果 URI 对象具有‘https’ URI 方案, Net::HTTP 会自动打开 TLS 验证。

uri = URI('https://example.com/')
Net::HTTP.get(uri) # => String

在以前的 Ruby 版本中,您需要使用“net/https”才能使用 HTTPS。这不再是真的。

代理

Net::HTTP 将自动从 http_proxy 环境变量(如果存在)创建代理。要禁用 http_proxy ,请将 nil 传递给代理地址。

您还可以创建自定义代理:

proxy_addr = 'your.proxy.host'
proxy_port = 8080

Net::HTTP.new('example.com', nil, proxy_addr, proxy_port).start { |http|
  # always proxy via your.proxy.addr:8080
}

有关更多详细信息和示例,例如需要用户名和密码的代理,请参阅 Net::HTTP.new

压缩

Net::HTTP 自动添加 Accept-Encoding 以压缩响应正文,并自动解压缩 gzip 和 deflate 响应,除非发送了 Range 标头。

可以通过Accept-Encoding: 身份标头禁用压缩。

HTTP 请求类

这是 HTTP 请求类层次结构。

HTTP 响应类

这是 HTTP 响应类层次结构。所有类都在 Net 模块中定义,并且是 Net::HTTPResponse 的子类。

HTTPUnknownResponse

对于未处理的 HTTP 扩展

HTTPInformation

1xx

HTTPContinue

100

HTTPSwitchProtocol

101

HTTPProcessing

102

HTTPEarlyHints

103

HTTPSuccess

2xx

HTTPOK

200

HTTPCreated

201

HTTPAccepted

202

HTTPNonAuthoritativeInformation

203

HTTPNoContent

204

HTTPResetContent

205

HTTPPartialContent

206

HTTPMultiStatus

207

HTTPAlreadyReported

208

HTTPIMUsed

226

HTTPRedirection

3xx

HTTPMultipleChoices

300

HTTPMovedPermanently

301

HTTPFound

302

HTTPSeeOther

303

HTTPNotModified

304

HTTPUseProxy

305

HTTPTemporaryRedirect

307

HTTPPermanentRedirect

308

HTTPClientError

4xx

HTTPBadRequest

400

HTTPUnauthorized

401

HTTPPaymentRequired

402

HTTPForbidden

403

HTTPNotFound

404

HTTPMethodNotAllowed

405

HTTPNotAcceptable

406

HTTPProxyAuthenticationRequired

407

HTTPRequestTimeOut

408

HTTPConflict

409

HTTPGone

410

HTTPLengthRequired

411

HTTPPreconditionFailed

412

HTTPRequestEntityTooLarge

413

HTTPRequestURITooLong

414

HTTPUnsupportedMediaType

415

HTTPRequestedRangeNotSatisfiable

416

HTTPExpectationFailed

417

HTTPMisdirectedRequest

421

HTTPUnprocessableEntity

422

HTTPLocked

423

HTTPFailedDependency

424

HTTPUpgradeRequired

426

HTTPPreconditionRequired

428

HTTPTooManyRequests

429

HTTPRequestHeaderFieldsTooLarge

431

HTTPUnavailableForLegalReasons

451

HTTPServerError

5xx

HTTPInternalServerError

500

HTTPNotImplemented

501

HTTPBadGateway

502

HTTPServiceUnavailable

503

HTTPGatewayTimeOut

504

HTTPVersionNotSupported

505

HTTPVariantAlsoNegotiates

506

HTTPInsufficientStorage

507

HTTPLoopDetected

508

HTTPNotExtended

510

HTTPNetworkAuthenticationRequired

511

还有一个 Net::HTTPBadResponse 异常,当出现协议错误时会引发该异常。

相关用法


注:本文由纯净天空筛选整理自ruby-lang.org大神的英文原创作品 HTTP类。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。