输入相同参数时,快速添加PercentEncoding结果不一样

问题描述 投票:0回答:1
      let path1 = "[path:test]"
      var set = CharacterSet()
      set.formUnion(.urlPathAllowed)

      let encodedPath1 = path1.addingPercentEncoding(withAllowedCharacters: set)
      let encodedPath2 = path1.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)

      print("Encoded Path 1: \(String(describing: encodedPath1))")
      print("Encoded Path 2: \(String(describing: encodedPath2))")

打印是(:在第一个中没有编码。)

Encoded Path 1: Optional("%5Bpath:test%5D")
Encoded Path 2: Optional("%5Bpath%3Atest%5D")
ios swift
1个回答
0
投票

根据 RFC 3986,只有第二种编码有效。相对路径(即您的字符串)中允许使用冒号,第一个路径组件除外(即第一个斜杠之前)。

addingPercentEncoding
处理内置 URL 相关字符类的方式与您在代码中创建的随机字符类不同。您在代码中创建的字符类无法编码复杂的逻辑,例如“允许使用冒号,除非它位于第一个斜杠之前”,即使它包含与内置 URL 字符类相同的字符

您可以通过查看 swift-corelibs-foundation 存储库中的

_CFStringCreateByAddingPercentEncodingWithAllowedCharacters
函数来了解其工作原理。这并不完全是在 Apple 平台上运行的,但它是一个很好的参考。

该函数调用

GetURLPredefinedCharacterSet
来查看传入的字符集是否是内置字符集之一。至关重要的是,
GetURLPredefinedCharacterSet
与内置字符集进行指针比较

for ( result = 0; result < kURLAllowedCharacterSetIllegal; ++result ) {
    // yes, I really want a pointer comparison because some of the sURLAllowedCharacterSets have the same bitmaps
    if ( characterSet == sURLAllowedCharacterSets[result] ) {
        break;
    }
}

它不会在

set
数组中找到您的
sURLAllowedCharacterSets
,因此它将返回
kURLAllowedCharacterSetIllegal
,并且
_CFStringCreateByAddingPercentEncodingWithAllowedCharacters
会将您的集合视为没有特殊含义的常规字符集,并且不会转义冒号,因为冒号字符在集合中。

如果您使用内置的

.urlPathAllowed
_CFStringCreateByAddingPercentEncodingWithAllowedCharacters
将沿着不同的路径走下去,并到达这里,在那里完成特殊处理。

我们可以看到,在

else
if (pastSlash)
分支中,它明确禁止使用冒号:

Boolean allowed = (ch <= 127) && (ch != ';') && (ch != ':') && ((sURLAllowedCharacters[ch] & allowedMask) != 0);

而在

if
分支中,没有
&& (ch != ';')

© www.soinside.com 2019 - 2024. All rights reserved.