Bagaimana cara membuat permintaan HTTP menggunakan Ruby on Rails?

235

Saya ingin mengambil informasi dari situs web lain. Karena itu (mungkin) saya harus membuat permintaan ke situs web itu (dalam kasus saya permintaan GET HTTP) dan menerima tanggapan.

Bagaimana saya bisa membuatnya di Ruby on Rails?

Jika memungkinkan, apakah ini pendekatan yang benar untuk digunakan dalam pengontrol saya?

pengguna502052
sumber

Jawaban:

330

Anda dapat menggunakan Net::HTTPkelas 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
João Silva
sumber
1
apa arti 'req' di sini?
sixty4bit
18
itu artinya meminta
Arthur Collé
1
Sepertinya ini mungkin permintaan pemblokiran, bukan?
Scott Eisenberg
di mana harus meletakkan kunci api?
user1735921
1
Hanya menambahkan bahwa www. seharusnya tidak perlu, biasanya tidak.
JackHasaKeyboard
111

Net :: HTTP dibangun ke dalam Ruby, tetapi mari kita hadapi itu, seringkali lebih mudah untuk tidak menggunakan gaya 1980-an yang rumit dan mencoba alternatif tingkat yang lebih tinggi:

Stefan
sumber
4
Atau ActiveResource, yang dilengkapi dengan Rails!
Marnen Laibow-Koser
8
Saya ingin berhati-hati agar tidak melakukannya karena Anda akan menambahkan lebih banyak dependensi ke aplikasi rel Anda. Semakin banyak ketergantungan berarti semakin banyak konsumsi memori dan juga permukaan serangan yang berpotensi lebih besar. Menggunakan Net::HTTPitu rumit tapi trade off tidak sepadan.
Jason Yeo
3
Ini harus menjadi jawaban yang diterima. Mengapa memprogram kapan Anda bisa menginstal banyak Permata?
Omikes
5
@JasonYeo Sangat tidak setuju. Memperkenalkan ketergantungan berarti Anda tidak menemukan kembali roda, dan Anda mendapat manfaat dari kerja keras yang telah dilakukan orang lain. Jika ada permata yang membuat hidup Anda lebih mudah, umumnya tidak ada alasan untuk tidak menggunakannya.
Marnen Laibow-Koser
1
@JasonYeo Saga leftpad hanya terjadi karena NPM menjalankan repositori buruk dan membiarkan penulis menghapus semua paketnya. Paket repo yang dikelola dengan baik tidak melakukan itu (dan lagi pula, itu OSS, sehingga Anda dapat dengan mudah melakukan mirror jika Anda mau). Yaitu, saga pad kiri bukan argumen yang menentang pengenalan dependensi secara umum, melainkan menentang pengelolaan repo yang buruk. Saya setuju dengan poin Anda yang lain, bahwa ketergantungan besar yang jauh lebih banyak daripada yang Anda butuhkan bisa berlebihan untuk nilai yang diberikannya.
Marnen Laibow-Koser
92

OpenURI adalah yang terbaik; sesederhana itu

require 'open-uri'
response = open('http://example.com').read
pengguna2454031
sumber
10
Penting untuk diingat, itu open-uritidak akan mengikuti arahan ulang.
yagooar
3
@yagooar yang luar biasa, mencegah pengalihan berbahaya sepertifile:///etc/passwd
gertas
1
Harap dicatat, bahwa itu tidak akan menutup koneksi. Gunakan 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')
Andrei Andrushkevich
sumber
13

Saya lebih suka httpclient daripada Net :: HTTP.

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

HTTParty adalah pilihan yang baik jika Anda membuat kelas yang merupakan klien untuk suatu layanan. Ini adalah mixin yang nyaman yang memberi Anda 90% dari yang Anda butuhkan. Lihat seberapa pendek klien Google dan Twitter dalam contoh .

Dan untuk menjawab pertanyaan kedua Anda: tidak, saya tidak akan menempatkan fungsi ini di controller - Saya akan menggunakan model jika mungkin untuk merangkum rincian (mungkin menggunakan HTTParty) dan cukup memanggilnya dari controller.

Mark Thomas
sumber
Dan bagaimana mungkin untuk melewati parameter dengan aman di URL? Contoh: http: //www.example.com/index.html? Param1 = test1 & param2 = test2. Maka saya perlu membaca dari parameter situs web lain dan menyiapkan tanggapan. Tetapi bagaimana saya bisa membaca parameter?
user502052
Apa maksud Anda, Anda perlu membaca parameter situs web lain? Bagaimana itu bisa terjadi? Apa yang ingin Anda capai?
Marnen Laibow-Koser
8

Dua cara favorit saya untuk mengambil konten URL adalah OpenURI atau Typhoeus .

OpenURI karena ada di mana-mana, dan Typhoeus karena sangat fleksibel dan kuat.

Manusia Timah
sumber
8

Berikut adalah kode yang berfungsi jika Anda membuat panggilan api REST di belakang 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
machzqcq
sumber