【问题标题】:Swift. Convert percent encoding symbols in string, to their ascii representation迅速。将字符串中的百分比编码符号转换为它们的 ascii 表示
【发布时间】:2021-12-05 00:41:52
【问题描述】:

我正在使用 Swift 框架 ASWebAuthenticationSession 以便通过浏览器为我的应用程序添加身份验证。处理凭据后,身份验证提供程序会发送带有特殊前缀的 URL,该 URL 会被我的应用程序拦截。网址格式如下:

mycallback:un%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=

现在我想创建一个提取参数值的方法。所以我使用 URLComponents。 我需要用'?'替换':',但是虽然它将百分比编码字符转换回ascii,但似乎无法正确解析url

(lldb) po URLComponents(string: "mycallback%3Fun%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=")

▿ Optional<URLComponents>
  ▿ some : mycallback%3Fun%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
    - path : "mycallback?un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0="


(lldb) po URLComponents(string: "mycallback%3Fun%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=")?.queryItems
nil

另一种方法是按原样使用截获的 URL 并获取方案+路径 但是我怎样才能从这个结构中查询参数呢?

(lldb) po URLComponents(string: "mycallback:un%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=")
▿ Optional<URLComponents>
  ▿ some : mycallback:un%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
    - scheme : "mycallback"
    - path : "un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0="

只有当我手动将百分比编码 p 符号提前转换为它们的 ascii 表示时,查询才看起来很好:

(lldb) po URLComponents(string: "mycallback?un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=")
▿ Optional<URLComponents>
  ▿ some : mycallback?un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
    - path : "mycallback"
    ▿ queryItems : 3 elements
      ▿ 0 : un=test
        - name : "un"
        ▿ value : Optional<String>
          - some : "test"
      ▿ 1 : as=1
        - name : "as"
        ▿ value : Optional<String>
          - some : "1"
      ▿ 2 : token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
        - name : "token"
        ▿ value : Optional<String>
          - some : "eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0="

所以我的问题是如何将所有百分比编码符号(格式为 '%' 后跟十六进制值)转换为它们的 ascii 表示?

【问题讨论】:

  • “base64 符号”不是“格式化为 '%' 后跟十六进制值。”你的意思是百分比编码。此查询中唯一的 base64 是 eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=,它是 base64 编码的 JSON ({"bbb":"Asda", "dscvg":"asascd"})。您想要哪些具体参数?正如所写,这是一个方案加路径。没有查询。我相信您可能正在寻找的是 www-form-urlencoded 解码。
  • @RobNapier,你说得对,我解决了我的问题。谢谢 !基本上我希望它能够根据参数从url中提取值(即,如果我调用extractValue(string:“token”)而不是我期望得到eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0 =。理想情况下,我希望采取路径(超出方案+路径)并使用它通过内置方法/框架提取值)
  • “ASCII 表示”是什么意思? ASCII 是现在很少使用的字符集。

标签: swift url base64 nsurlcomponents


【解决方案1】:

您有一个 URL,其中方案为 mycallback,路径实际上是一个查询。你只需要解析和调整它。

func decodedParameters(string: String) -> [URLQueryItem]? {
    var c = URLComponents()
    c.query = URLComponents(string: data)?.path
    return c.queryItems
}


if let parameters = decodedParameters(string: data),
   let token = parameters.first(where: { $0.name == "token"})?.value {
    print(token)
}

// eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=

如果您经常这样做,您可能更愿意创建一个扩展以使其更容易:

extension Array where Element == URLQueryItem {
    subscript(_ key: String) -> String? {
        first(where: { $0.name == key})?.value
    }
}

let parameters = decodedParameters(string: data) ?? []

if let token = parameters["token"] {
    print(token)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2015-05-08
    • 2019-09-29
    • 2021-05-26
    • 1970-01-01
    • 2011-08-24
    相关资源
    最近更新 更多