如果我像这样编码一个字符串:

var escapedString = originalString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

它没有逃脱斜杠/。

我搜索并找到了这段Objective C代码:

NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                        NULL,
                        (CFStringRef)unencodedString,
                        NULL,
                        (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                        kCFStringEncodingUTF8 );

是否有一个更简单的方法来编码一个URL,如果没有,我怎么写在Swift?


当前回答

斯威夫特4:

这取决于您的服务器所遵循的编码规则。

苹果提供了这个类方法,但它没有报告它遵循哪种RCF协议。

var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!

使用这个有用的工具,你应该保证这些字符的编码为你的参数:

$(美元符号)变为%24 &(&)变成%26 +(+)变成%2B ,(逗号)变成%2C :(冒号)变成%3A ; (分号)变成%3B =(等于)变成%3D ? (问号)变成%3F @(商业A / At)变成%40

换句话说,谈到URL编码,您应该遵循RFC 1738协议。

Swift不包括+字符的编码,但它可以很好地使用这三个@:?识字课。

因此,要正确编码每个参数,.urlHostAllowed选项是不够的,你还应该添加特殊字符,例如:

encodedParameter = parameter.replacingOccurrences(of: "+", with: "%2B")

希望这能帮助那些变得疯狂的人搜索这些信息。

其他回答

Swift 4和5(谢谢@sumizome的建议。感谢@FD_和@derickito的测试)

var allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed
allowedQueryParamAndKey.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)

斯威夫特3

let allowedQueryParamAndKey =  NSCharacterSet.urlQueryAllowed.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)

Swift 2.2(借用Zaph's,修正url查询键和参数值)

var allowedQueryParamAndKey =  NSCharacterSet(charactersInString: ";/?:@&=+$, ").invertedSet
paramOrKey.stringByAddingPercentEncodingWithAllowedCharacters(allowedQueryParamAndKey)

例子:

let paramOrKey = "https://some.website.com/path/to/page.srf?a=1&b=2#top"
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
// produces:
"https%3A%2F%2Fsome.website.com%2Fpath%2Fto%2Fpage.srf%3Fa%3D1%26b%3D2%23top"

以下是陈布莱恩回答的一个简短版本。我猜urlQueryAllowed允许控制字符通过,这很好,除非它们在查询字符串中形成键或值的一部分,在这一点上它们需要转义。

斯威夫特4:

这取决于您的服务器所遵循的编码规则。

苹果提供了这个类方法,但它没有报告它遵循哪种RCF协议。

var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!

使用这个有用的工具,你应该保证这些字符的编码为你的参数:

$(美元符号)变为%24 &(&)变成%26 +(+)变成%2B ,(逗号)变成%2C :(冒号)变成%3A ; (分号)变成%3B =(等于)变成%3D ? (问号)变成%3F @(商业A / At)变成%40

换句话说,谈到URL编码,您应该遵循RFC 1738协议。

Swift不包括+字符的编码,但它可以很好地使用这三个@:?识字课。

因此,要正确编码每个参数,.urlHostAllowed选项是不够的,你还应该添加特殊字符,例如:

encodedParameter = parameter.replacingOccurrences(of: "+", with: "%2B")

希望这能帮助那些变得疯狂的人搜索这些信息。

斯威夫特3

在Swift 3中增加了percentencoding

let originalString = "test/test"
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(escapedString!)

输出:

测试%2F测试

斯威夫特1

在ios7及以上版本中,有stringByAddingPercentEncodingWithAllowedCharacters

var originalString = "test/test"
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
println("escapedString: \(escapedString)")

输出:

测试%2F测试

以下是有用的(倒置的)字符集:

URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
URLUserAllowedCharacterSet      "#%/:<>?@[\]^`

如果你想要转义一组不同的字符,创建一个set: 添加“=”字符的示例:

var originalString = "test/test=42"
var customAllowedSet =  NSCharacterSet(charactersInString:"=\"#%/<>?@\\^`{|}").invertedSet
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)
println("escapedString: \(escapedString)")

输出:

测试% 2Ftest % 3D42

使用实例验证集合中不存在的ascii字符。

func printCharactersInSet(set: NSCharacterSet) {
    var characters = ""
    let iSet = set.invertedSet
    for i: UInt32 in 32..<127 {
        let c = Character(UnicodeScalar(i))
        if iSet.longCharacterIsMember(i) {
            characters = characters + String(c)
        }
    }
    print("characters not in set: \'\(characters)\'")
}

斯威夫特5:

extension String {
    var urlEncoded: String? {
        let allowedCharacterSet = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "~-_."))
        return self.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet)
    }
}

print("\u{48}ello\u{9}world\u{7}\u{0}".urlEncoded!) // prints Hello%09world%07%00
print("The string ü@foo-bar".urlEncoded!) // prints The%20string%20%C3%BC%40foo-bar


这些答案对我都没用。当url包含非英语字符时,我们的应用程序崩溃了。

 let unreserved = "-._~/?%$!:"
 let allowed = NSMutableCharacterSet.alphanumeric()
     allowed.addCharacters(in: unreserved)

 let escapedString = urlString.addingPercentEncoding(withAllowedCharacters: allowed as CharacterSet)

根据您要做的事情的参数,您可能只想创建自己的字符集。上面允许使用英文字符,并且-._~/?%$!: