安全地发送 base64 编码的字符串作为查询参数

Safely sending base64 encoded string as query parameter

在我的应用中,我需要向服务器发送一个 base64 编码的字符串作为查询参数,例如

&data=AwGZnyx+JUi0PFJoyYSEDpgtlrxP(cut...)==

问题是,当我的字符串中没有加号时,一切正常:另一方面,每次有加号时,服务器代码都无法正常运行。

我注意到有转义函数(例如 addingPercentEncoding),但它们不适用于加号。

除了删除所有加号 "manually"(例如,使用正则表达式),我还能做些什么吗?

目前如果我使用任何东西都可以正常工作:

string.replacingOccurrences(of: "+", with: "%2B")

服务器可能将 + 符号解释为 space,因为它经常在查询参数中用作 space 的替代品。 addPercentEncoding 不会帮助你,因为它只翻译非 ASCII 字符。

您需要手动将 + 替换为 %2B

..虽然

NSString 有一个版本 addPercentEncoding that also takes a CharacterSet as a parameter. So you could create a Characterset with all the base64 characters in it except + using init(charactersIn:)

let safeChars = Characterset(charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrtuvwxyz0123456789/=")

构造 URL 的一个好方法是使用 URLComponents。这应该适用于几乎所有情况,示例如下所示:

let base64 = "AwGZnyx+JUi0PFJoyYSEDpgtlrxP(cut...)=="
var components = URLComponents(string: "https://example.com")
components?.queryItems = [ URLQueryItem(name: "data", value: "AwGZnyx+JUi0PFJoyYSEDpgtlrxP(cut...)==") ]

let url = components?.url

结果:

https://example.com?data=AwGZnyx+JUi0PFJoyYSEDpgtlrxP(cut...)%3D%3D

但是,在您的特定情况下,服务器似乎没有正确处理 +,您需要像上面那样解决该问题。更好的解决方法是更改​​服务器以正确处理 URL.

let base64 = "AwGZnyx+JUi0PFJoyYSEDpgtlrxP(cut...)=="
var components = URLComponents(string: "https://example.com")
components?.queryItems = [ URLQueryItem(name: "data", value: base64) ]

let urlString = components?.string.replacingOccurrences(of: "+", with: "%2B")

结果:

https://example.com?data=AwGZnyx%252BJUi0PFJoyYSEDpgtlrxP(cut...)%3D%3D