ฉันจะดาวน์โหลดไฟล์จาก URL และบันทึกใน Rails ได้อย่างไร?


197

ฉันมี URL ไปยังรูปภาพที่ฉันต้องการบันทึกในเครื่องเพื่อให้ฉันสามารถใช้คลิปหนีบกระดาษเพื่อสร้างภาพขนาดย่อสำหรับแอปพลิเคชันของฉัน วิธีที่ดีที่สุดในการดาวน์โหลดและบันทึกภาพคืออะไร? (ฉันดูการจัดการไฟล์ทับทิม แต่ไม่เจออะไรเลย)

คำตอบ:


316

ลองสิ่งนี้:

require 'open-uri'
open('image.png', 'wb') do |file|
  file << open('http://example.com/image.png').read
end

1
วิธีนี้ใช้ได้ผล ขอบคุณ ฉันลองมันในรูป ภาพไม่ได้เขียนลงไฟล์อย่างถูกต้อง ราวกับว่ามันได้รับความเสียหายหรืออะไร คุณสามารถแนะนำให้ฉันทำสิ่งนี้ได้เหมือนกันในแอปพลิเคชั่น Rails ฉันสามารถใช้สิ่งนี้ในแอปพลิเคชั่น Rails ได้หรือไม่?
Alok Swain

ใช่คุณสามารถใช้มันได้ในแอพพลิเคชั่นราง ไฟล์ที่เขียนไม่ถูกต้องอาจเป็นเพราะฉันลืมเปิดปลายทางในโหมดเขียนไบนารี่ ฉันจะแก้ไขมันทันที
เลวี

78
นี่จะอ่านไฟล์ทั้งหมดในหน่วยความจำ วิธีที่ดีที่สุดคือIO.copy_stream(open('http://example.com/image.png'), 'destination.png')
janko-m

3
rails 5, 2016, ฉันไม่จำเป็นต้องrequire 'open-uri'ใช้รหัสใต้
Mirror318

1
คำตอบนี้ไม่ได้ผลสำหรับฉัน คำตอบที่ถูกต้องอยู่ที่นี่: stackoverflow.com/a/29743394/1536309
Blair Anderson

147

รุ่นที่สั้นกว่า:

require 'open-uri'
download = open('http://example.com/image.png')
IO.copy_stream(download, '~/image.png')

หากต้องการใช้ชื่อไฟล์เดิม:

IO.copy_stream(download, "~/#{download.base_uri.to_s.split('/')[-1]}")

2
และมีประสิทธิภาพมากขึ้นเนื่องจากเอาท์พุทไม่ได้เก็บไว้เป็นสตริงในหน่วยความจำ +1
Itay Grudev

2
แม้ว่ามันจะมีประโยชน์จริง ๆ ที่มีคำตอบทั้งคู่ปรากฏขึ้นดังนั้นผู้คนอย่างฉันสามารถเห็นได้ทั้งคู่ลองคิดถึงความแตกต่างแล้วเลือกคำตอบนี้อย่างมีเหตุผลด้วยเหตุผลที่เหมาะสม :)
Maxwell Evans

30

หากคุณใช้ PaperClip การดาวน์โหลดจาก URL จะถูกจัดการโดยอัตโนมัติ

สมมติว่าคุณมีสิ่งที่ชอบ:

class MyModel < ActiveRecord::Base
  has_attached_file :image, ...
end

ในแบบจำลองของคุณเพียงระบุภาพเป็น URL ลักษณะเช่นนี้ (เขียนด้วยมือเปล่าโดยเจตนา):

@my_model = MyModel.new
image_url = params[:image_url]
@my_model.image = URI.parse(image_url)

คุณอาจต้องการวางวิธีนี้ในแบบจำลองของคุณ สิ่งนี้จะทำงานได้ดีบนระบบแฟ้มชั่วคราวของ Heroku

คลิปหนีบกระดาษจะเอามาจากที่นั่น

แหล่งที่มา: เอกสารประกอบคลิปหนีบกระดาษ


4
สำหรับผู้ค้นหาในอนาคตคลิปหนีบกระดาษไม่อนุญาตสิ่งนี้ตามค่าเริ่มต้น: medium.com/in-the-weeds/…
Alex Dunae

14

ฉันคิดว่านี่เป็นวิธีที่ชัดเจนที่สุด:

require 'open-uri'

File.write 'image.png', open('http://example.com/image.png').read

ปราชญ์ฉันใหม่สำหรับรางซึ่งฉันสามารถเพิ่มรหัสนี้ในรูปแบบหรือตัวควบคุมหรือในมุมมอง
adarsh

1
ขึ้นอยู่กับ แต่โดยทั่วไปคุณจะทำอะไรแบบนี้ในแบบจำลองหรือวิธีการควบคุม ในบริบท Rails คุณน่าจะดีกว่าโดยใช้เครื่องมือของเฟรมเวิร์กเช่น ActiveStorage แทนที่จะเขียนลงดิสก์โดยตรง
Sage Ross

10

ตรวจสอบNet :: HTTPในไลบรารีมาตรฐาน เอกสารประกอบให้ตัวอย่างหลายอย่างเกี่ยวกับวิธีการดาวน์โหลดเอกสารโดยใช้ HTTP


2
คำตอบนี้ต้องการการมองเห็นที่มากขึ้นเนื่องจากKernel#openไม่เพียง แต่ช่วยให้สามารถเข้าถึงไฟล์ได้เท่านั้น แต่ยังสามารถประมวลผลการร้องขอได้ด้วยการใส่สัญลักษณ์ไปป์ (เช่นopen("| ls")) ดังนั้นจึงอาจนำไปสู่ความเสี่ยงด้านความปลอดภัยที่ร้ายแรงโดยใช้ตัวแปรอินพุตในการโต้แย้งของKernel#openดังนั้นจึงอาจนำไปสู่ความเสี่ยงด้านความปลอดภัยร้ายแรงโดยใช้การป้อนข้อมูลตัวแปรอาร์กิวเมนต์ของ
ConorB
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.