2012-01-13 91 views
2

使用ruby 1.9.2-p290。我碰到一個問題來試圖解析URI像下面這樣:解析具有大括號的URI,URI :: InvalidURIError:錯誤的URI(不是URI?)

require 'uri' 
my_uri = "http://www.anyserver.com/getdata?anyparameter={330C-B5A2}" 
the_uri = URI.parse(my_uri) 

發出以下錯誤:

URI::InvalidURIError: bad URI(is not URI?) 

我需要比每次都是這樣編碼的花括號中的不同的解決方案:

new_uri = URI.encode("http://www.anyserver.com/getdata?anyparameter={330C-B5A2}") 
=> "http://www.anyserver.com/getdata?anyparameter=%7B330C-B5A2%7D" 

現在我可以像往常一樣解析new_uri,但每次需要時都必須執行此操作。不用每次都做到這一點,最簡單的方法是什麼?

我發佈我自己的解決方案,因爲我沒有看到這完全像我解決它。


# Accepts URIs when they contain curly braces 
# This overrides the DEFAULT_PARSER with the UNRESERVED key, including '{' and '}' 
module URI 
    def self.parse(uri) 
    URI::Parser.new(:UNRESERVED => URI::REGEXP::PATTERN::UNRESERVED + "\{\}").parse(uri) 
    end 
end 

現在我可以用含有花括號URI使用URI.parse(URI),並不會引發錯誤。

+0

爲什麼你必須用URI解析它?你是否正在使用URI對URL進行其他操作,還是有其他參數需要編碼? – 2012-01-13 07:45:16

+0

是的,基本上我修改了一個廣泛使用它的gem,並且替換所有代碼並不是很好,所以我更喜歡在一個地方更改URI#parse行爲:) – 2012-01-13 14:20:24

回答

5
# Need to not fail when uri contains curly braces 
# This overrides the DEFAULT_PARSER with the UNRESERVED key, including '{' and '}' 
# DEFAULT_PARSER is used everywhere, so its better to override it once 
module URI 
    remove_const :DEFAULT_PARSER 
    unreserved = REGEXP::PATTERN::UNRESERVED 
    DEFAULT_PARSER = Parser.new(:UNRESERVED => unreserved + "\{\}") 
end 

跟進同樣的問題,因爲DEFAULT_PARSER到處使用,它能夠更好地替代它完全insted的只是爲URI#解析方法。另外,這樣可以避免每次爲實例化新的Parser對象分配內存。

+0

你應該接受你的答案。它的工作原理,謝謝! – mydoghasworms 2012-11-13 05:40:52

2

RFC 1738 - http://www.faqs.org/rfcs/rfc1738.html意味着你必須編碼括號

Thus, only alphanumerics, the special characters "$-_.+!*'(),", and 
reserved characters used for their reserved purposes may be used 
unencoded within a URL. 
+0

謝謝!,但是我沒有太多一個選擇,因爲uri是由一個外部服務提供的,並沒有完全遵循RFC,所以使用了花括號:) – 2012-01-13 04:01:59