2013-02-26 32 views
5

我想使用端点和路径或主机和路径创建一个URL。不幸的是URI.join不允许这样做:在Rails中使用主机和多个路径字符串创建一个URL

pry(main)> URI.join "https://service.com", "endpoint", "/path" 
=> #<URI::HTTPS:0xa947f14 URL:https://service.com/path> 
pry(main)> URI.join "https://service.com/endpoint", "/path" 
=> #<URI::HTTPS:0xabba56c URL:https://service.com/path> 

和我要的是:"https://service.com/endpoint/path"。我怎么能在Ruby/Rails中做到这一点?

编辑:由于URI.join有一些缺点,我很想用File.join

URI.join("https://service.com", File.join("endpoint", "/path")) 

你觉得呢?

+1

退房:http://stackoverflow.com/questions/8900782/how-do-i-safely-join-relative-url-segments – 2013-02-26 14:39:08

回答

6

URI.join的工作方式与您期望的<a>标签的工作方式类似。

您正在加入example.com,endpoint,/path,因此/path会将您带回到域的根目录,而不是追加它。

您需要以/结束端点,而不是以/开始路径。

URI.join "https://service.com/", "endpoint/", "path" 
=> #<URI::HTTPS:0x007f8a5b0736d0 URL:https://service.com/endpoint/path> 

编辑:按照在下面的评论你的要求,试试这个:

def join(*args) 
    args.map { |arg| arg.gsub(%r{^/*(.*?)/*$}, '\1') }.join("/") 
end 

测试:

> join "https://service.com/", "endpoint", "path" 
=> "https://service.com/endpoint/path" 
> join "http://example.com//////", "///////a/////////", "b", "c" 
=> "http://example.com/a/b/c" 
+0

感谢。但是,我不想关心斜线(缺少斜杠,双斜线等),因为'URI.join(“https://service.com/”,“endpoint”,“path”)也是无法正常工作。所以在我的情况下,整个'URI.join'和简单的字符串连接一样有用。你知道任何“自动”连接路径在URI中的方法,而无需照顾斜线? – mrzasa 2013-02-26 14:06:35

+0

@mrzasa,请尝试我添加到我上面的答案的功能。 – Dogbert 2013-02-26 14:58:16

+1

@mrzasa,当给定它所需的值时,'URI.join'完美地工作。虽然你不想关心,但是你可以这样做,因为这就是程序员所做的事情。我们必须意识到我们传递给方法的价值内容,以便返回我们期望的结果。以下是需要思考的问题:“有两次我被问到 - '请问巴贝奇先生,如果你把错误的数字放在机器上,答案是否会出来? ......我无法正确理解可能引发这样一个问题的那种混淆思想。“- Charles Babbage,哲学家生平的段落 – 2013-02-26 15:25:05

3

看起来URI.join检查反斜杠字符的存在“ /'来计算出url路径中的文件夹。因此,如果您错过了路径中的尾部斜杠'/',它将不会将其视为文件夹,并省略它。检查了这一点:

URI.join("https://service.com", 'omitted_part', 'omitted_again', 'end_point_stays').to_s 
# =>"https://service.com/end_point_stays" 

在这里,如果我们试图加入的话ONLY,第一个和最后PARAMS只停留,其余的都省略了,其中第一个参数是,绝对URI与协议&最后一个参数是,终点。

所以,如果你想包含的文件夹组件,加斜杠在每个文件夹组分,路径的那么只有它被认为是部分:

URI.join("https://service.com", 'omitted_no_trailing_slash', 'omitted_again', 'stays/', 'end_point_stays').to_s 
# => "https://service.com/stays/end_point_stays" 

还有一个要考虑有趣的事情是,如果你提供的第一个参数路径它的作用如下:

URI.join("https://service.com/omitted_because_no_trailing_slash", 'end_point_stays').to_s 
# => "https://service.com/end_point_stays" 
URI.join("https://service.com/stays_because_of_trailing_slash/", 'end_point_stays').to_s 
# => "https://service.com/stays_because_of_trailing_slash/end_point_stays" 
URI.join("https://service.com/safe_with_trailing_slash/omitted_because_no_trailing_slash", 'end_point_stays').to_s 
# => "https://service.com/safe_with_trailing_slash/end_point_stays" 
相关问题