當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


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類。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。