【问题标题】:How can I ignore a parameter in a URL?如何忽略 URL 中的参数?
【发布时间】:2019-10-17 02:55:22
【问题描述】:

我的应用程序对 URL 进行解码,我注意到当它遇到“&”时,该过程会停止并忽略 URL 的其余部分。似乎 URLComponents 正在将 URL 分解为多个部分 - 我的必需参数和它认为是参数的那个。

 hxxp://www.g.com/url?u=http://a.com/test&d=another
  - scheme : "hxxp"
  - host : "www.g.com"
  - path : "/url"
  ▿ queryItems : 2 elements
    ▿ 0 : u=http://a.com/test
      - name : "u"
      ▿ value : Optional<String>
        - some : "http://a.com/test"
    ▿ 1 : d=another
      - name : "d"
      ▿ value : Optional<String>
        - some : "another"

我需要的是“u=”之后的完整网址。

这是对解码字符串的函数的初始调用:

if (fullDecode.contains("?u=")) {
            initialDecode = getQueryStringParameter(urlToAttempt: fullDecode, param: "u")!

这里是返回解码字符串的函数:

func getQueryStringParameter(urlToAttempt: String, param: String) -> String? {
        guard let urlDecoded = URLComponents(string: urlToAttempt) else { return nil }
        print(urlDecoded)
        return urlDecoded.queryItems?.first(where: { $0.name == param })?.value
    }

对于这段代码,如果 url 是“http://www.g.com/url?u=http://a.com/test&d=another”,它将返回“http://a.com/test”——其他所有内容都被删除了。我希望它返回“http://a.com/test&d=another

有没有一种方法可以让我使用 URLComponents 做到这一点,或者我是否需要编写自定义代码来支持这一点?

更新 如果我更改传递给“hxxp://www.g.com/url?u=http://a.com/test%26d=another”的 url,URLComponents 会返回完整的 url,并且 &d=another 不变。我现在将尝试在发送到函数之前对特殊字符进行百分比编码,看看是否能解决问题。

第二次更新

这是我需要解码的经过大量修改的链接类型:

hxxps://ue.pt.com/v2/url?u=https-3A__oe.le.com_-3Fauthkey-3D-2521IB-2DCRV-2DqQ88-26cid-3DBACDF2ED353D-26id-3DBACDF2EFB61D353D-2521549-26parId-3Droot-26o-3DOneUp&d=DwMGaQ&c=WNpQK9bFmT89misLWAzsd66s44iGV-VujF_o4whjrfc&r=Ej_UhLznQMBqt3H3IYBQkjyx4xqdnS9mLiYA&m=HOBrLfxamFr4PYdACIR-A49th_oIe3MW69N7X-E&s=bXWSJ8gaSbKSlNuIf30S7Qsa6RcMKA-EOvP577XUyq0&e=

这些链接是生成的,这就是为什么我无法控制链接的构建方式。我需要能够将此链接解码为清晰的 URL。我有特殊混淆的字典,例如“-3A__”是“://”上面失败的地方是你看到 &d=DwM... 它没有被编码,这就是 URLComponents 失败的地方:

https://oe.le.com/?authkey=!IB-CRV-qQ88&cid=BACDF2ED353D&id=BACDF2EFB6353D!549&parId=root&o=OneUp

这有帮助吗?

【问题讨论】:

  • 这种行为似乎合乎逻辑。我读到:http://...url...?key1=param1&key2=param2,其中 key1 = u,param1 是 a.com/test,key2 = d,param2 = another。我们怎么知道“&key2=param2”不是一个新的参数,而是在param1里面呢?我猜错过了一些转义。
  • Url-in-url 应该是percent encoded
  • @Rob - 网址就是这样。它根本不是百分比编码的。我可以在它到达函数之前或在函数中对其进行百分比编码,但我不确定这是否能解决 &d 仍然被视为 URLComponents 的参数
  • 另外,http://a.com/test&amp;d=another — 不是有效的 URL,就像它的查询无效:它应该以 ? 而不是 &amp; 开头。所以,URLComponents 只会以正确的方式解析它。
  • “我想我不明白。我从来没有说过我有问题? - 它始终是与号 (&)” ...您在修改后的示例中提供的 URL 有一个 -3F(这是 ? 在包含在 u 参数中的 URL 中,但在您的原始示例)。这里的问题是哪些参数与哪个 URL(主 URL,或隐藏在 u 参数中的 URL)和缺少的 ? 之间的混淆是解释实际情况的关键。最重要的是,不用担心,因为您修改后的示例清楚地说明了发生了什么。

标签: swift url decode


【解决方案1】:

您可以使用“?u=”作为分隔符拆分您的 URL 字符串,并使用 this function 获取第二个数组元素

否则,您可以循环所有查询项并将它们连接起来。

【讨论】:

    【解决方案2】:

    URLComponents 在这种情况下会正确解析您的网址。

    url 查询中的&amp; 可以并且可能永远属于外部URL,因为内部URL 甚至不启动查询部分(那里没有?)。

    所以hxxp://www.g.com/url?u=http://a.com/test&amp;d=another被解析为:

      - scheme : "hxxp"
      - host : "www.g.com"
      - path : "/url"
      ▿ queryItems : 2 elements
        ▿ 0 : u=http://a.com/test
          - name : "u"
          ▿ value : Optional<String>
            - some : "http://a.com/test"
        ▿ 1 : d=another
          - name : "d"
          ▿ value : Optional<String>
            - some : "another"
    

    但是hxxp://www.g.com/url?u=http://a.com/test?d=another&amp;d 替换为?d)被解析为

    - scheme: "hxxp"
    - host: "www.g.com"
    - path: "/url"
    ▿ queryItems: 1 element
      ▿ u=http://a.com/test?d=another
        - name: "u"
        ▿ value: Optional("http://a.com/test?d=another")
          - some: "http://a.com/test?d=another"
    

    在这里,您在u 查询参数中获得了所有内心的URL

    【讨论】:

    • 有趣的问题是,与外部 URL 的 u 参数关联的内部 URL 是否为 http://a.com/test?d=Foo&amp;e=Bar
    • 谢谢,但我无法控制我正在解码的值是什么。我收到的 url 在 URL 中可能有也可能没有 &=。如果没有,则应用程序可以正常工作。我需要能够将 url 发送到已经百分比编码的函数,或者如果存在,则忽略来自 urlcomponents 的 url 中的&符号。
    • @Nutrion,在不违反标准的情况下,您将无能为力
    • @Rob,检查了一下,外部 url 会认为 e 是它的参数。因此,如果内部 url 有针对该查询参数的计划,则应使用百分比编码。
    【解决方案3】:

    如果您修改后的问题,请向我们提供以下网址:

    let string = "hxxps://ue.pt.com/v2/url?u=https-3A__oe.le.com_-3Fauthkey-3D-2521IB-2DCRV-2DqQ88-26cid-3DBACDF2ED353D-26id-3DBACDF2EFB61D353D-2521549-26parId-3Droot-26o-3DOneUp&d=DwMGaQ&c=WNpQK9bFmT89misLWAzsd66s44iGV-VujF_o4whjrfc&r=Ej_UhLznQMBqt3H3IYBQkjyx4xqdnS9mLiYA&m=HOBrLfxamFr4PYdACIR-A49th_oIe3MW69N7X-E&s=bXWSJ8gaSbKSlNuIf30S7Qsa6RcMKA-EOvP577XUyq0&e="
    

    显然-3A__://_-3F/?-26&amp;-3D=,等等。所以如果你这样做:

    let replacements = [
        "-3A__": "%3A//",
        "_-3F": "/%3F",
        "-26": "%26",
        "-3D": "%3D",
        "-2D": "%2D",
        "-25": "%25"
    ]
    
    let result = replacements.reduce(string) { (string, tuple) -> String in
        return string.replacingOccurrences(of: tuple.key, with: tuple.value)
    }
    
    let components = URLComponents(string: result)!
    for item in components.queryItems! {
        print(item.name, item.value!)
    }
    

    您最终会使用以下参数调用hxxps://ue.pt.com/v2/url

    u https://oe.le.com/?authkey=%21IB-CRV-qQ88&cid=BACDF2ED353D&id=BACDF2EFB61D353D%21549&parId=root&o=OneUp
    d DwMGaQ
    c WNpQK9bFmT89misLWAzsd66s44iGV-VujF_o4whjrfc
    r Ej_UhLznQMBqt3H3IYBQkjyx4xqdnS9mLiYA
    m HOBrLfxamFr4PYdACIR-A49th_oIe3MW69N7X-E
    s bXWSJ8gaSbKSlNuIf30S7Qsa6RcMKA-EOvP577XUyq0
    e 
    

    这里的关键是参数authkeycididparIdo是用于oe.le.com URL,但所有其他参数d、@987654340 @、rmse不是编码为u 一部分的 URL 的一部分,而是ue.pt.com URL 的单独参数.您不希望将它们作为 oe.le.com 的 URL 的一部分。

    我的原始答案如下。


    让我们尝试从另一个方向解决这个问题。

    考虑一下我正在构建 URL 的这两种情况。首先,我对g.com 有一个参数,即u,这是一个有参数的URL:

    var components = URLComponents(string: "http://g.com")!
    components.queryItems = [
        URLQueryItem(name: "u", value: "http://a.com/test?d=foo&e=bar")
    ]
    let url = components.url
    

    你会看到 url 是

    http://g.com/?u=http://a.com/test?d%3Dfoo%26e%3Dbar

    请注意,=&amp; 分别转义为 %3D%26,因为它们是隐藏在与 u 参数关联的值中的 URL 的参数,而不是实际的参数g.com URL 本身。

    另一种情况是g.com的URL有ude三个参数:

    var components2 = URLComponents(string: "http://g.com")!
    components2.queryItems = [
        URLQueryItem(name: "u", value: "http://a.com/test"),
        URLQueryItem(name: "d", value: "foo"),
        URLQueryItem(name: "e", value: "bar")
    ]
    let url2 = components2.url
    

    产生:

    http://g.com/?u=http://a.com/test&amp;d=foo&amp;e=bar

    请注意,=&amp; 没有进行百分比转义,因为它们是 g.com URL 的参数,而不是包含在 u 值中的 a.com URL 的参数。

    您似乎给了我们一个类似于第二种情况生成的 URL,但坚持认为它确实与第一种情况相似。如果这是真的,那么原始 URL 的百分比编码不正确并且是无效的。更有可能的是,第二种情况适用,并且参数属于g.com URL,而不是u 值的一部分。


    请注意,您给我们的网址是:

    hxxp://www.g.com/url?u=http://a.com/test&amp;d=another

    如果d 确实是a.com URL 的参数,则该URL 将是http://a.com/test?d=another,而不是http://a.com/test&amp;d=another(注意?,而不是&amp;。)

    所以这进一步证明d 参数确实是g.com url 的一个参数,而u 参数确实只是http://a.com/test

    【讨论】:

    • 我编辑了这个问题以添加一个关于我如何使用它的真实场景。对于我收到的 URL,并不是所有的特殊字符都被编码。出于某种原因,我现在尝试在发送到函数之前对 & 符号进行百分比编码,但它不起作用。我仍在使用它。感谢您迄今为止的所有帮助!
    【解决方案4】:

    我想发布我为纠正此问题所做的工作,但提交的所有答案都帮助我走上了这条路。发送到函数的代码如下所示:

    if (fullDecode.contains("?u=")) {
        fullDecode = fullDecode.replacingOccurrences(of: "&", with: "%26")
        initialDecode = getQueryStringParameter(urlToAttempt: fullDecode, param: "u")!
    

    如果 uitextview fullDecode 包含“?u=”,那么我知道视图中有文本。文本应该是完全混淆的 URL,如果它包含“&”,我会手动将其转换为 %26。在我使用自定义字典进行其他转换之前,这将被发送到 URLComponents 函数。

       func getQueryStringParameter(urlToAttempt: String, param: String) -> String? {
            guard let urlDecoded = URLComponents(string: urlToAttempt) else { return nil }
            return urlDecoded.queryItems?.first(where: { $0.name == param })?.value
        }
    

    我真的想太多了。

    【讨论】:

    • 我不认为这是正确的。看看你的网址。你在u 参数中有那些-26 序列。这些应该替换为%26,但现有的&amp; 应该更改为&amp;26。见my revised answer
    • 是的,我知道这很令人困惑。但是我收到这些的来源似乎并不总是用 %26 重写 & ,这就是问题所在。问题是我依靠带有 URLComponents 的函数来完成它可以做的繁重工作,然后我将剩余部分发送到另一个函数以使用我的自定义字典重写值。 URLComponents 函数没有发回完整的 URL 来处理我的问题。一切似乎都按照现在的预期方式工作,但是如果特殊字符存在,我必须在发送到 urlcomponent 函数之前对其进行编码。
    猜你喜欢
    • 1970-01-01
    • 2021-11-04
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    相关资源
    最近更新 更多