Encode '+' using URLComponents in Swift

前端 未结 4 798
死守一世寂寞
死守一世寂寞 2020-12-11 00:56

This is how I add query params to a base URL:

let baseURL: URL = ...
let queryParams: [AnyHashable: Any] = ...
var components = URLComponents(url: baseURL, r         


        
4条回答
  •  旧时难觅i
    2020-12-11 01:33

    As pointed out in the other answers, the "+" character is valid in a query string, this is also stated in the query​Items documentation.

    On the other hand, the W3C recommendations for URI addressing state that

    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.

    This can be achieved by "manually" building the percent encoded query string, using a custom character set:

    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
    

    Another option is to "post-encode" the plus character in the generated percent-encoded query string:

    let queryParams = ["foo":"a+b", "bar": "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
    

提交回复
热议问题