这是我如何将查询参数添加到基本URL:
let baseURL: URL = ... let queryParams: [AnyHashable: Any] = ... var components = URLComponents(url: baseURL,resolvingAgainstBaseURL: false) components?.queryItems = queryParams.map { URLQueryItem(name: $0,value: "\($1)") } let finalURL = components?.url
当其中一个值包含符号时,就会出现问题.由于某种原因,它在最终的URL中没有编码为+,而是保留.如果我自己编码并传递+,则NSURL编码%,’plus’变为%2B.
问题是我如何在NSURL的实例中拥有+?
附:我知道,如果我自己构造一个查询字符串,然后简单地将结果传递给NSURL的构造函数init?(字符串:),我甚至不会遇到这个问题.
解决方法
正如在其他答案中指出的那样,“”字符在
一个查询字符串,这也在
一个查询字符串,这也在
queryItems
文档.
另一方面,
W3C recommendations for URI addressing
说明
Within the query string,the plus sign is reserved as shorthand notation for a space. Therefore,real plus signs must be encoded. This method was used to make query URIs easier to pass in systems which did not allow spaces.
这可以通过“手动”构建来实现
百分比编码的查询字符串,使用自定义字符集:
let queryParams = ["foo":"a+b","bar": "a-b","baz": "a b"] var components = URLComponents() var cs = CharacterSet.urlQueryAllowed cs.remove("+") components.scheme = "http" components.host = "www.example.com" components.path = "/somepath" components.percentEncodedQuery = queryParams.map { $0.addingPercentEncoding(withAllowedCharacters: cs)! + "=" + $1.addingPercentEncoding(withAllowedCharacters: cs)! }.joined(separator: "&") let finalURL = components.url // http://www.example.com/somepath?bar=a-b&baz=a%20b&foo=a%2Bb
另一种选择是对生成的加号进行“后编码”
百分比编码的查询字符串:
let queryParams = ["foo":"a+b","baz": "a b"] var components = URLComponents() components.scheme = "http" components.host = "www.example.com" components.path = "/somepath" components.queryItems = queryParams.map { URLQueryItem(name: $0,value: $1) } components.percentEncodedQuery = components.percentEncodedQuery? .replacingOccurrences(of: "+",with: "%2B") let finalURL = components.url print(finalURL!) // http://www.example.com/somepath?bar=a-b&baz=a%20b&foo=a%2Bb