为什么 Swift URL 的 init?(string: String,relativeTo: URL?) 只添加协议?

问题描述 投票:0回答:1

当我这样做时

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 或其他内容的一部分,还是在其他地方记录的?

swift url rfc
1个回答
0
投票

正如您所注意到的,这是由于开头的

//
造成的。根据 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,它允许您更明确、更安全地查询和修改部件。

© www.soinside.com 2019 - 2024. All rights reserved.