在iOS Native中,有时候我们在内置浏览器中打开一个页面时,向页面传入的参数无法解析;
通常是因为参数中含有+号或=号;
在有些页面中,在接收这些参数时会显示用 decodeURIComponent 来解码下参数,此时,如果参数中含有 +号或=号,解码就会失败;
因此在调用url前需要先将参数 urlEncode一下;
网上现在流行较多的方式是:
//将原始的url编码为合法的url
func urlEncoded() -> String {
let encodeUrlString = self.addingPercentEncoding(withAllowedCharacters:
.urlQueryAllowed)
return encodeUrlString ?? ""
}
//将编码后的url转换回原始的url
func urlDecoded() -> String {
return self.removingPercentEncoding ?? ""
}
可惜这个方式并不会编码 + 或着 = 号;
所以,此时可以使用下面的方法来构建url:
/**
@param host "h5.xxx.com"
@param scheme "http"
@param path "/List"
*/
static func createURL(host:String, scheme:String, path:String, args:Dictionary<String, String>) -> URL? {
var urlComponents = URLComponents()
urlComponents.scheme = scheme
urlComponents.host = host
urlComponents.path = path
var queryItems = Array<URLQueryItem>()
args.keys.forEach { keyName in
let item = URLQueryItem(name: keyName, value: args[keyName])
queryItems.append(item)
}
urlComponents.queryItems = queryItems
urlComponents.percentEncodedQuery = urlComponents.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
print("urlComponents.url!:\(urlComponents.url!)")
return urlComponents.url
}
说明:
尽管+ & = 等符号都可以出现在 url 当中,但是如果当这些符号出现在参数值内,就可能会导致意外的情况发生,例如:因为&用作查询参数之间的分隔符,如果用在参数值内这会过早地终止您的值,并且将+转换为空格字符;
W3C HTML规范的第4.10.22.6节(URL编码表单数据)指出application/x-www-form-urlencoded请求还应该用+字符替换空格字符(并在不应该被转义的字符中包含星号)。 不幸的是, URLComponents不能正确地百分比转义这个,所以Apple建议你在检索URLComponents对象的url属性之前手动百分比转义它:
components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
let url = components.url!