จะทำการร้องขอ HTTP โดยใช้ Ruby บน Rails ได้อย่างไร


235

ฉันต้องการรับข้อมูลจากเว็บไซต์อื่น ดังนั้น (อาจ) ฉันควรทำการร้องขอไปยังเว็บไซต์นั้น (ในกรณีของฉันคือคำขอ HTTP GET) และรับการตอบกลับ

ฉันจะสร้างมันใน Ruby on Rails ได้อย่างไร

ถ้าเป็นไปได้มันเป็นวิธีการที่ถูกต้องในการใช้งานในคอนโทรลเลอร์ของฉันหรือไม่?

คำตอบ:


329

คุณสามารถใช้Net::HTTPคลาสของรูบี้:

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' หมายถึงอะไรที่นี่
sixty4bit

18
มันหมายถึงการร้องขอ
Arthur Collé

1
ดูเหมือนว่านี่อาจเป็นการร้องขอการบล็อกใช่ไหม
Scott Eisenberg

จะใส่คีย์ api ได้ที่ไหน
user1735921

1
เพียงเพิ่มที่ www ไม่ควรจำเป็นโดยทั่วไปไม่จำเป็น
JackHasaKeyboard

111

Net :: HTTP ถูกสร้างขึ้นใน Ruby แต่ลองดูกันบ่อยครั้งมันจะง่ายกว่าที่จะไม่ใช้สไตล์ที่ยุ่งยากในช่วงปี 1980 และลองทางเลือกในระดับที่สูงขึ้น:


4
หรือ ActiveResource ซึ่งมาพร้อมกับ Rails!
Marnen Laibow-Koser

8
ฉันต้องการที่จะระมัดระวังในการทำเช่นนี้เพราะคุณจะเพิ่มการอ้างอิงมากขึ้นในแอพทางรถไฟของคุณ การพึ่งพามากขึ้นหมายถึงการใช้หน่วยความจำมากขึ้นและพื้นผิวการโจมตีที่ใหญ่ขึ้น การใช้Net::HTTPนั้นยุ่งยาก แต่การแลกเปลี่ยนไม่คุ้มค่า
Jason Yeo

3
นี่ควรเป็นคำตอบที่ยอมรับได้ ทำไมโปรแกรมเมื่อคุณสามารถติดตั้งอัญมณีได้มากมาย?
omikes

5
@ JasonYeo ไม่เห็นด้วยอย่างยิ่ง การแนะนำการพึ่งพาหมายความว่าคุณไม่ต้องคิดค้นใหม่และคุณจะได้รับประโยชน์จากการทำงานหนักที่คนอื่นทำไปแล้ว หากมีอัญมณีที่ทำให้ชีวิตของคุณง่ายขึ้นโดยทั่วไปก็ไม่มีเหตุผลที่ดีที่จะไม่ใช้มัน
Marnen Laibow-Koser

1
@JasonYeo Saga leftpad เกิดขึ้นเพราะ NPM มีที่เก็บไม่เพียงพอและให้ผู้เขียนลบแพ็คเกจทั้งหมดของเขา แพคเกจ repos ที่มีการจัดการอย่างถูกต้องไม่ทำเช่นนั้น (และเป็น OSS ดังนั้นคุณสามารถมิเรอร์ได้อย่างง่ายดายหากคุณต้องการ) นั่นคือ Saga leftpad ไม่ใช่ข้อโต้แย้งในการแนะนำการพึ่งพาโดยทั่วไป แต่เป็นการต่อต้านการจัดการ repo ที่ไม่ดี ฉันเห็นด้วยกับประเด็นอื่น ๆ ของคุณว่าการพึ่งพาอาศัยกันที่ยิ่งใหญ่เกินกว่าที่คุณต้องการจะเกินค่าที่คุณได้รับ
Marnen Laibow-Koser

92

OpenURI นั้นดีที่สุด มันง่ายเหมือน

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

10
สิ่งสำคัญคือต้องเตือนว่าopen-uriจะไม่ติดตามการเปลี่ยนเส้นทาง
yagooar

3
@yagooar ซึ่งยอดเยี่ยมป้องกันการเปลี่ยนเส้นทางที่เป็นอันตรายเช่นfile:///etc/passwd
gertas

1
โปรดทราบว่ามันจะไม่ปิดการเชื่อมต่อ ใช้stackoverflow.com/a/4217269/820501
ShockwaveNN


13

ฉันชอบhttpclientมากกว่า Net :: HTTP

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

HTTParty เป็นตัวเลือกที่ดีถ้าคุณสร้างคลาสที่เป็นไคลเอนต์สำหรับบริการ มันเป็นสูตรผสมที่สะดวกสบายที่ให้ 90% ของสิ่งที่คุณต้องการ ดูวิธีการระยะสั้นลูกค้า Google และทวิตเตอร์อยู่ในตัวอย่าง

และเพื่อตอบคำถามที่สองของคุณ: ไม่ฉันจะไม่ใส่ฟังก์ชั่นนี้ในคอนโทรลเลอร์ - ฉันจะใช้โมเดลแทนถ้าเป็นไปได้ที่จะสรุปรายละเอียด (อาจใช้ HTTParty) และเรียกมันจากคอนโทรลเลอร์


และเป็นไปได้อย่างไรที่จะส่งพารามิเตอร์อย่างปลอดภัยใน URL? เช่น http: //www.example.com/index.html? param1 = test1 & param2 = test2 ถ้าอย่างนั้นฉันต้องอ่านจากพารามิเตอร์ของเว็บไซต์อื่นและเตรียมการตอบกลับ แต่ฉันจะอ่านพารามิเตอร์ได้อย่างไร
user502052

คุณหมายถึงอะไรคุณต้องอ่านพารามิเตอร์ของเว็บไซต์อื่น มันจะเป็นไปได้ยังไง คุณพยายามทำอะไรให้สำเร็จ
Marnen Laibow-Koser

8

โปรดของฉันสองวิธีที่จะคว้าเนื้อหาของ URL ที่มีทั้งOpenURIหรือTyphoeus

OpenURI เพราะมันอยู่ทุกหนทุกแห่งและ Typhoeus เพราะมันยืดหยุ่นและทรงพลังมาก


8

นี่คือรหัสที่ใช้งานได้หากคุณทำการเรียกใช้ REST api หลังพร็อกซี:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.