6

我想使用端点和路径或主机和路径创建 URL。不幸URI.join的是不允许这样做:

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"))

你怎么看?

4

3 回答 3

9

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"
于 2013-02-26T13:50:01.273 回答
3

Looks like URI.join checks for the presence of slash character '/' to figures out the folder in the url path. So, if you missed the trailing slash '/' in the path it will not treat it as folder, and omit it. Check this out:

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

Here, if we try to JOIN THE WORDS ONLY, first and last params only stay, rest are omitted, where first param is, absolute uri with protocol & last param is, the end point.

So, if you want to include the folder component, add trailing slash in each folder-component, then only it is considered part of the path:

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

One more interesting thing to consider is that, if you are providing path in first parameter it acts as follows:

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"
于 2016-05-01T10:15:52.910 回答
0

我制作了一个脚本,让您可以执行以下操作:

SmartURI.join('http://example.com/subpath', 'hello', query: { token: secret })
=> "http://example.com/subpath/hello?token=secret"

https://gist.github.com/zernel/0f10c71f5a9e044653c1a65c6c5ad697

于 2017-08-25T08:29:54.930 回答