当我这样做时
let baseUrl = URL(string: "ftp://www.foobar.com/foo/bar/")
let finalUrl = URL(string: "//barfoo.com/bar/foo", relativeTo: baseUrl)
print(finalUrl?.absoluteString ?? "ooops")
它打印
ftp://barfoo.com/bar/foo
这是预期的行为吗?这有记录在某处吗?
[编辑] 我只是想知道,因为我希望所有的东西,包括服务器和路径都将从基本网址中获取,如下所示:
let baseUrl = URL(string: "ftp://www.foobar.com/foo/bar/")
let finalUrl = URL(string: "boo/far", relativeTo: baseUrl)
print(finalUrl?.absoluteString ?? "ooops")
打印
ftp://www.foobar.com/foo/bar/boo/far
。
为什么在第一个示例中服务器和基本 url 中的其他所有内容都被忽略?是因为开头的
//
吗?这是某些 RFC 或其他内容的一部分,还是在其他地方记录的?
正如您所注意到的,这是由于开头的
//
造成的。根据 URI RFC,URI 的格式为:
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
hier-part = "//" authority path-abempty
/ path-absolute
/ path-rootless
/ path-empty
当您的 URI 以
//
开头时,您表示它应该替换权限和路径,事实也确实如此。如第 3.3 节中所述,path-absolute
不能以
//
开头:
/ path-absolute ; begins with "/" but not "//"
如果您的目的是在不修改权限(userinfo、host、port)的情况下替换路径,那么您可以传递绝对路径(以/
开头)而不是权限和路径(以
//
开头):
let finalUrl = URL(string: "/barfoo.com/bar/foo", relativeTo: baseUrl)
// ftp://www.foobar.com/barfoo.com/bar/foo
如果你想附加一个路径,你可以传递一个无根路径(不以/
开头):
let finalUrl = URL(string: "barfoo.com/bar/foo", relativeTo: baseUrl)
// ftp://www.foobar.com/foo/barfoo.com/bar/foo
对于比这更复杂的操作,您绝对应该查看 URLComponents,它允许您更明确、更安全地查询和修改部件。