Làm cách nào để tạo một yêu cầu HTTP bằng Ruby on Rails?


235

Tôi muốn lấy thông tin từ một trang web khác. Do đó (có thể) tôi nên đưa ra yêu cầu cho trang web đó (trong trường hợp của tôi là yêu cầu HTTP GET) và nhận được phản hồi.

Làm thế nào tôi có thể thực hiện điều này trong Ruby on Rails?

Nếu có thể, đó có phải là một cách tiếp cận đúng để sử dụng trong bộ điều khiển của tôi không?

Câu trả lời:


329

Bạn có thể sử dụng Net::HTTPlớp của Ruby :

require 'net/http'

url = URI.parse('http://www.example.com/index.html')
req = Net::HTTP::Get.new(url.to_s)
res = Net::HTTP.start(url.host, url.port) {|http|
  http.request(req)
}
puts res.body

1
'req' có nghĩa là gì ở đây?
Sixty4bit

18
nó có nghĩa là yêu cầu
Arthur Collé

1
Có vẻ như đây có thể là một yêu cầu chặn, phải không?
Scott Eisenberg

Đặt chìa khóa api ở đâu?
dùng1735921

1
Chỉ cần thêm rằng www. không cần thiết, nó thường không.
JackHasaPal

111

Net :: HTTP được tích hợp vào Ruby, nhưng hãy đối mặt với nó, thường thì không dễ sử dụng kiểu thập niên 1980 rườm rà của nó và thử một giải pháp thay thế cấp cao hơn:


4
Hoặc ActiveResource, đi kèm với Rails!
Marnen Laibow-Koser

8
Tôi muốn thận trọng không làm như vậy vì bạn sẽ thêm nhiều phụ thuộc vào ứng dụng rails của bạn. Phụ thuộc nhiều hơn có nghĩa là tiêu thụ bộ nhớ nhiều hơn và cũng có khả năng bề mặt tấn công lớn hơn. Sử dụng Net::HTTPlà cồng kềnh nhưng đánh đổi không đáng.
Jason Yeo

3
Đây phải là câu trả lời được chấp nhận. Tại sao chương trình khi bạn chỉ có thể cài đặt nhiều Đá quý?
omike

5
@JasonYeo Rất không đồng ý. Giới thiệu các phụ thuộc có nghĩa là bạn không phát minh lại bánh xe và bạn được hưởng lợi từ công việc khó khăn mà những người khác đã làm. Nếu một viên đá quý tồn tại giúp cuộc sống của bạn dễ dàng hơn, thường không có lý do chính đáng nào để không sử dụng nó.
Marnen Laibow-Koser

1
@JasonYeo Câu chuyện bên trái chỉ xảy ra do NPM chạy kho lưu trữ kém và để tác giả xóa tất cả các gói của mình. Các repos gói được quản lý đúng cách không làm điều đó (và dù sao, đó là OSS, vì vậy bạn có thể dễ dàng phản chiếu nếu bạn muốn). Đó là, saga bàn phím trái không phải là một đối số chống lại việc giới thiệu phụ thuộc nói chung, mà là chống lại việc quản lý repo kém. Tôi đồng ý với quan điểm khác của bạn, rằng một sự phụ thuộc lớn làm nhiều hơn mức bạn cần có thể là quá mức cần thiết cho giá trị mà nó cung cấp.
Marnen Laibow-Koser

92

OpenURI là tốt nhất; nó đơn giản như

require 'open-uri'
response = open('http://example.com').read

10
Điều quan trọng là phải cảnh báo, điều đó open-urisẽ không tuân theo các chuyển hướng.
yagooar

3
@yagooar, điều này thật tuyệt vời, ngăn chặn các chuyển hướng độc hại nhưfile:///etc/passwd
gertas

1
Xin lưu ý rằng nó sẽ không đóng kết nối. Sử dụng stackoverflow.com/a/4217269/820501
ShockwaveNN

82
require 'net/http'
result = Net::HTTP.get(URI.parse('http://www.example.com/about.html'))
# or
result = Net::HTTP.get(URI.parse('http://www.example.com'), '/about.html')

13

Tôi thích httpclient hơn Net :: HTTP.

client = HTTPClient.new
puts client.get_content('http://www.example.com/index.html')

HTTParty là một lựa chọn tốt nếu bạn tạo một lớp là khách hàng cho một dịch vụ. Đó là một mixin tiện lợi cung cấp cho bạn 90% những gì bạn cần. Xem các khách hàng của Google và Twitter ngắn như thế nào trong các ví dụ .

Và để trả lời câu hỏi thứ hai của bạn: không, tôi sẽ không đưa chức năng này vào bộ điều khiển - thay vào đó tôi sẽ sử dụng một mô hình để đóng gói các chi tiết (có thể sử dụng HTTParty) và chỉ cần gọi nó từ bộ điều khiển.


Và làm thế nào có thể vượt qua các tham số an toàn trong URL? Ví dụ: http: //www.example.com/index.html? Param1 = test1 & param2 = test2. Sau đó, tôi cần phải đọc từ các thông số trang web khác và chuẩn bị mặt nạ. Nhưng làm thế nào tôi có thể đọc các tham số?
dùng502052

Ý bạn là gì, bạn cần đọc các thông số của trang web khác? Làm thế nào mà thậm chí có thể? Bạn đang cố gắng để đạt được điều gì?
Marnen Laibow-Koser

8

Hai cách ưa thích của tôi để lấy nội dung của URL là OpenURI hoặc Typhoeus .

OpenURI vì nó ở khắp mọi nơi và Typhoeus vì nó rất linh hoạt và mạnh mẽ.


8

Đây là mã hoạt động nếu bạn đang thực hiện cuộc gọi api REST phía sau proxy:

require "uri"
require 'net/http'

proxy_host = '<proxy addr>'
proxy_port = '<proxy_port>'
proxy_user = '<username>'
proxy_pass = '<password>'

uri = URI.parse("https://saucelabs.com:80/rest/v1/users/<username>")
proxy = Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass)

req = Net::HTTP::Get.new(uri.path)
req.basic_auth(<sauce_username>,<sauce_password>)

result = proxy.start(uri.host,uri.port) do |http|
http.request(req)
end

puts result.body
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.