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?

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

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:


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


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

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.


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.


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.