2

使用URLComponents's时queryItems,我发现如果您有一个查询项,其值包含一定百分比的编码字符,在我的情况下 a/被编码为%2F,那么如果您从包含此类查询项URLComponents的 URL 构造一个对象,则改变对象String的查询项列表URLComponents,然后如果您尝试URL通过调用对象来获取 a .urlURLComponents那么查询项将丢失其百分比编码。

这是我在操场上测试的代码:

import UIKit

// --- Part 1 ---
print("--- Part 1 ---\n")

let startURL = "https://test.com/test.jpg?X-Test-Token=FQdzEPH%2F%2F%2F"
var components = URLComponents(string: startURL)!

if let compURL = components.url {
    print(URL(string: startURL)! == compURL) // True
    print(startURL)
    print(compURL)
}

// --- Part 2 ---
print("\n--- Part 2 ---\n")

let startURLTwo = "https://test.com/test.jpg?X-Test-Token=FQdzEPH%2F%2F%2F"
let finalURL = "https://test.com/test.jpg?X-Test-Token=FQdzEPH%2F%2F%2F&foo=bar"
var componentsTwo = URLComponents(string: startURLTwo)!

let extraQueryItem = URLQueryItem(name: "foo", value: "bar")
componentsTwo.queryItems!.append(extraQueryItem)

if let compURLTwo = componentsTwo.url {
    print(URL(string: finalURL)! == compURLTwo) // False
    print(finalURL)
    print(compURLTwo)
}

如果这样可以更容易地理解正在发生的事情,这是一张图片:

在此处输入图像描述

4

2 回答 2

3

percentEncodedQuery如果您有一个已经被百分比编码的查询,您应该使用:

let startURL = "https://test.com/test.jpg"
var components = URLComponents(string: startURL)!
components.percentEncodedQuery = "X-Test-Token=FQdzEPH%2F%2F%2F"

if let compURL = components.url {
    print(compURL)
}

或者您可以将其指定为未转义(并且它保持未转义,因为没有必要/在查询中转义字符):

let startURL = "https://test.com/test.jpg"
var components = URLComponents(string: startURL)!
components.queryItems = [URLQueryItem(name: "X-Test-Token", value: "FQdzEPH///")]

if let compURL = components.url {
    print(compURL)
}

如果您必须更新queryItems,请确保percentEncodedQuery在最后设置:

let startURL = "https://test.com/test.jpg"
let encodedQuery = "X-Test-Token=FQdzEPH%2F%2F%2F"
var components = URLComponents(string: startURL)!
components.queryItems = [URLQueryItem(name: "foo", value: "bar, baz, & qux")]
if let query = components.percentEncodedQuery {
    components.percentEncodedQuery = query + "&" + encodedQuery
} else {
    components.percentEncodedQuery = encodedQuery
}

if let compURL = components.url {
    print(compURL)
}
于 2017-12-21T23:01:23.070 回答
0

RFC 3986明确指出 URL 查询可能包含该/字符。它不需要进行百分比编码。当您专门修改任何查询参数时,URLComponents只需遵循标准并取消编码%2F即可。/

在第一种情况下,您根本不修改任何内容,因此 URL 保持不变。第二,修改组件的查询参数属性。因此,URLComponents从更新的查询参数数组构建一个新的查询字符串。在此过程中,如果将它们全部归一化并删除不必要的百分比编码。

于 2017-12-21T20:42:08.520 回答