Errno :: EADDRNOTAVAIL เมื่อส่งคำขอไปยัง api จาก Rails บน Docker

Aug 15 2020

สิ่งที่ฉันต้องการทำ

ฉันต้องการได้รับการตอบสนองของข้อมูลหนังสือโดยการกดปุ่ม google books api จาก Book model of Rails

ข้อผิดพลาดที่เกิดขึ้น

web_1 | Errno::EADDRNOTAVAIL (Failed to open TCP connection to :80 (Address not available-connect(2) for nil port 80)):
web_1 |
web_1 | app/models/book.rb:24:in `search'
web_1 | app/controllers/books_controller.rb:3:in `search'

รหัส

กด API โดยใช้คีย์เวิร์ด (ชื่อหนังสือผู้แต่ง ฯลฯ ) ที่ส่งจากแบบฟอร์ม

class BooksController <ApplicationController
  def search
    @results = Book.search(params[:book_search][:search_key_word])
  end
end

เนื่องจากมีอักขระที่ไม่ใช่ ASCII จึงถูกเข้ารหัสโดยใช้url_encodeวิธีการ

class Book <ApplicationRecord
  class << self
    def search(key_word)
      api_endpoint = ERB::Util.url_encode("https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20")
      response = Net::HTTP.get(URI.parse(api_endpoint)) # I'm getting the above error.
      JSON.parse(response)
    end
  end
end

การดำเนินการคำสั่ง curl สำหรับจุดสิ้นสุดเดียวกันแน่นอนว่าจะให้การตอบสนองที่เหมาะสม

มีบางอย่างเกี่ยวกับการใช้นักเทียบท่าหรือไม่? มันขึ้นอยู่กับลินุกซ์อัลไพน์https://hub.docker.com/layers/ruby/library/ruby/2.6.6-alpine/images/sha256-95d5b6bf7084a6a0f04b48a7fc1c533ccb15e1550c670ff589ef56e620f40286?context=explore

สิ่งแวดล้อม

  • นักเทียบท่า 2.3.0.4
  • นักเทียบท่าเขียน 3.8.2
  • รางคอนเทนเนอร์รูปฐานทับทิม: 2.6.6-alpine
  • ทับทิม 2.6.6
  • ราง 6.0.3.2

ฉันจะขอบคุณถ้าคุณสามารถสอนฉันได้หากคุณมีความคิดใด ๆ
ขอบคุณสำหรับความร่วมมือ.

คำตอบ

1 Tatsuro Aug 16 2020 at 07:03

แก้ไข.

สาเหตุคือ

ERB::Util.url_encode("https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20")

เมื่อสตริงอักขระส่งคืนเมื่อเข้ารหัสในส่วนนี้ถูกส่งผ่านไปยัง URI.parse ตามเดิม URI :: Generic จะถูกส่งกลับ ดูเหมือนว่าโฮสต์และโครงร่างของ uri เป็นศูนย์และไม่สามารถรับได้อย่างถูกต้อง เนื่องจากถูกส่งไปยัง Net :: HTTP.get ตามที่เป็นอยู่จึงเกิดข้อผิดพลาดเช่นชื่อเรื่อง

URI.encodeเลิกใช้งานแล้วดังนั้นฉันจึงต้องการเข้ารหัสด้วยวิธีอื่น สุดท้ายเมื่อดำเนินการ URI.parse กับสตริงอักขระที่เข้ารหัสโดยใช้WEBrick::HTTPUtils.#escapeอินสแตนซ์ของ URI :: HTTP จะถูกส่งกลับและชุดรูปแบบ ฯลฯ ถูกตั้งค่าอย่างถูกต้องและได้รับการแก้ไข

ขอบคุณมาก.

เอกสารอ้างอิง

def search(key_word)
  uri = URI.parse(WEBrick::HTTPUtils.escape("https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20"))
  response = Net::HTTP.get_response(uri)
  JSON.parse(response.body)
end