簡體   English   中英

Ruby: URI::InvalidURIError (URI 只能是 ascii

[英]Ruby: URI::InvalidURIError (URI must be ascii only

require 'uri'
uri = URI.parse 'http://dxczjjuegupb.cloudfront.net/wp-content/uploads/2017/10/Оуэн-Мэтьюс.jpg'

The browsers have no problem with http://dxczjjuegupb.cloudfront.net/wp-content/uploads/2017/10/Оуэн-Мэтьюс.jpg so I'm asking myself if this ruby class is a little bit outdated? 我應該完全放棄它還是做一些錯誤處理......

通過問自己這個問題,我得到了答案:

begin
  uri = URI.parse(url)
rescue URI::InvalidURIError
  uri = URI.parse(URI.escape(url))
end

你怎么看:

url = URI.escape(url) unless url.ascii_only?
URI.parse(url)

有了對所有URI.escape (也稱為URI.encode )的URI.encode ,這些方法已被 Ruby 2.7 正式淘汰- 即它們現在產生可見的URI.escape is obsolete警告消息,以前它們只是已棄用。

不幸的是,據我所知,Ruby 的標准庫URI類沒有提供任何替代方法來處理包含非 ASCII 字符的 URI,這些字符在當今非常普遍 - <sarcasm>現在網絡已經國際化</sarcasm >.

我想出的最佳解決方案是使用包含我們應得的URI類的可尋址gem - 它處理世界必須扔給它的一切,您可以使用#display_uri方法獲得“HTTP 安全”URI:

Addressable::URI.parse("http://example.com/Оуэн-Мэтьюс.jpg")
=> #<Addressable::URI:0xc8 URI:http://example.com/Оуэн-Мэтьюс.jpg>
Addressable::URI.parse("http://example.com/Оуэн-Мэтьюс.jpg").display_uri.to_s
=> "http://example.com/%D0%9E%D1%83%D1%8D%D0%BD-%D0%9C%D1%8D%D1%82%D1%8C%D1%8E%D1%81.jpg"

Addressable::URI還帶有各種好東西,例如端口推斷(您可以判斷 URL 最初是否包含端口規范,或者您可以不在乎)和 URL 規范化(給定一個基本 URL,取一個可能的相對 URL)並生成一個絕對 URL)。

以下是如何在net/http使用它:

response = Net::HTTP.start(url.host, url.inferred_port, 
        :use_ssl => url.scheme == 'https') do |http|
    req = Net::HTTP::Get.new(url.display_uri.request_uri)
end

我有同樣的錯誤:

Ruby:URI::InvalidURIError(URI 只能是 ascii

用我的代碼,但我的錯誤是它是一個舊項目,而且 i18n 已經過時了。 解決了,很簡單:

bundle update

您可以映射 URL 字符並轉義非 ASCII 字符。 像這樣的東西:

url.chars.map { |char| char.ascii_only? ? char : CGI.escape(char) }.join
URI.encode('your-url')

這對我有用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM