如何在没有百分比编码的情况下在 Swift URL 中包含重音字符?
Posted
技术标签:
【中文标题】如何在没有百分比编码的情况下在 Swift URL 中包含重音字符?【英文标题】:How to include accented characters in Swift URL without percent encoding? 【发布时间】:2020-08-08 14:42:55 【问题描述】:我正在尝试向需要保留重音字符而不是对它们进行百分比编码的 URL 发出 Web 请求。例如。 é
不得更改为 e%CC%81
。我无法改变这一点。
这些是不允许使用百分比编码的字符:AaÁáBbCcDdEeÉéFfGgHhIiÍíJjKkLlMmNnOoÓóÖöŐőPpQqRrSsTtUuÚúÜüŰűVvWwXxYyZz0123456789-
这是我需要的网址示例
https://helyesiras.mta.hu/helyesiras/default/suggest?q=hány%20éves
您可以在您的网络浏览器中尝试此 url 以确认其工作。 (该站点使用匈牙利语。)如果您尝试使用此 url (
https://helyesiras.mta.hu/helyesiras/default/suggest?q=ha%CC%81ny%20e%CC%81ves
) 的正确百分比编码版本,则该网站将给出错误。 (还有匈牙利语。)
我有我的自定义编码器来获取这个 URL 字符串。但是,要发出网络请求,我需要将 String
转换为 URL
。
我尝试了两种方法:
URL(string:)
let urlStr = "https://helyesiras.mta.hu/helyesiras/default/suggest?q=hány%20éves"
var url = URL(string: urlStr)
// ERROR: Returns nil
URLComponents
与 percentEncodedQueryItems
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "helyesiras.mta.hu"
urlComponents.path = "/helyesiras/default/suggest"
urlComponents.percentEncodedQueryItems = [ // ERROR: invalid characters in percent encoded query items
URLQueryItem(name: "q", value: "hány%20éves")
]
let url = urlComponents.url
是否可以在没有 Foundation API 检查其有效性的情况下创建 URL?或者我可以创建自己的验证规则吗?
【问题讨论】:
您使用了错误的 URLComponents 属性,它应该是queryItems
而不是 percentEncodedQueryItems
=> urlComponents.queryItems = [URLQueryItem(name: "q", value: "hány éves")]
结果查询部分应该是 "h%C3%A1ny%20%C3%A9ves"
@LeoDabus 我知道,这就是问题所在,urlComponents
在我不想要 urlPercent 编码时强制使用 percentEncoding。我需要 á 留下 á 和 é 留下 é。
你需要修复服务器端。百分比编码正确
关于在没有百分比编码的情况下在 Safari 中是否可以工作并没有任何意义
【参考方案1】:
Safari 对 URL 进行百分比编码。您只是以不同的方式对其进行百分比编码(并且在某种程度上您的服务器正在拒绝)。 Safari 发送给服务器的是:
GET /helyesiras/default/suggest?q=h%C3%A1ny%20%C3%A9ves HTTP/1.1
您可以使用Charles 进行检查。您的网站运行正常,似乎不需要未编码的 URL。
发送未编码的 URL 是无效的,而 Safari 则不会。 URLSession 也没有办法做到这一点。您必须直接连接到套接字并构建自己的 HTTP 堆栈,这很有可能,但我认为您不想这样做。
正如 Leo 所说,正确的做法是使用:
URLQueryItem(name: "q", value: "hány éves")
将%20
替换为未编码的“”,这样您就不会对百分比进行双重编码。
如果你手动编码字符串,你会发现相同的编码:
print("hány éves".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed))
// Optional("h%C3%A1ny%20%C3%A9ves")
(但你应该使用 URLComponents。addingPercentEncoding
非常容易出错。)
á
的首选 UTF-8 编码是作为 Unicode 代码点 LATIN SMALL LETTER A WITH ACUTE (C3 A1)。您正在编码的是拉丁小写字母 A (61),后跟 COMBINING ACUTE ACCENT (CC 81)。我怀疑您的服务器没有应用 Unicode 规范化规则。不幸的是,修复很简单:使用 URLComponents,您将获得与 Safari 相同的正确行为。
【讨论】:
以上是关于如何在没有百分比编码的情况下在 Swift URL 中包含重音字符?的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有 Storyboards/Unwindng Segues 的情况下在 Swift 中使用 UIViewControllerAnimatedTransitioning?
如何在没有 segue 的情况下在 Swift 3 中将数据从 VC 传递到另一个?
iOS - 如何在没有第三方框架的情况下在 Swift 中创建自定义动画横幅
如何在没有手动限制的情况下在一侧扩展 ggplot 条形刻度而不是另一侧