Как я могу игнорировать параметр в URL? - PullRequest
1 голос
/ 31 мая 2019

Мое приложение декодирует 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"

Мне нужен полный URL-адрес после "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, или мне нужно сделать собственный код для поддержки этого?

Обновление Если я изменю URL-адрес, который передается на "hxxp: //www.g.com/url? U = http://a.com/test%26d=another", URLComponents возвращает полный URL-адрес с другим целым & d =. Я сейчас попробую в процентах кодировать специальный символ перед отправкой в ​​функцию и посмотреть, решит ли это проблему.

Второе обновление

Вот сильно модифицированный тип ссылки, которую мне нужно декодировать:

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__" is ": //" Там, где вышеприведенный сбой, вы видите, где & d = DwM ... Это не закодировано, и вот где URLComponents терпит неудачу:

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

Помогает ли это?

Ответы [ 4 ]

1 голос
/ 31 мая 2019

URLComponents правильно анализирует ваш URL в этом случае.

& в запросе URL может и может когда-либо принадлежать внешнему URL, потому что внутренний 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"

Но hxxp://www.g.com/url?u=http://a.com/test?d=another (&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"

И здесь вы получаете все свои внутренние URL в u параметре запроса.

1 голос
/ 31 мая 2019

Если ваш пересмотренный вопрос, вы дадите нам следующий URL:

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 - &, -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 

Ключздесь параметры authkey, cid, id, parId и o предназначены для URL oe.le.com, но все остальные параметры d, c, r, m, s и e являются , а не частью URL, закодированной как часть u, а скорее являются отдельными параметрами для ue.pt.com URL.Вы не хотите включать их как часть URL-адреса для oe.le.com.

Мой оригинальный ответ приведен ниже.


Давайте попробуем подойти к этой проблеме с другой стороны.

Рассмотрим эти два сценария, в которых я создаю 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

Обратите внимание, что = и & в процентах экранированы как %3D и %26, соответственно, поскольку они являются параметрами URL-адреса, скрытого внутри соответствующего значения.с параметром u, а не параметрами самого URL g.com.

Альтернативный сценарий состоит в том, что URL g.com имеет три параметра: u, d и e:

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&d=foo&e=bar

Обратите внимание, что = и & не являются процентами, сбежавшими в процентахпоскольку они являются параметрами URL-адреса g.com, а не параметрами URL-адреса a.com, содержащимися в значении u.

Вы, похоже, предоставляете нам URL-адрес, подобный второму сценарию, но настаиваете на том, чтобыэто действительно похоже на первый сценарий.Если это правда, исходный URL не был правильно закодирован в процентах и ​​является недействительным.Скорее всего, применяется второй сценарий, и параметры имеют URL-адрес g.com, не предназначенный для включения в значение u.


Обратите внимание, что вы далинам URL:

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

Если бы d действительно был параметром a.com URL, то этот URL был бы http://a.com/test?d=another, а неhttp://a.com/test&d=another (обратите внимание на ?, а не &.)

Так что это еще одно доказательство того, что параметр d действительно является параметром g.com url, и что uпараметр на самом деле просто http://a.com/test.

0 голосов
/ 31 мая 2019

Я хотел опубликовать, что я сделал, чтобы исправить это, но все ответы, которые были представлены, помогли мне идти по этому пути.Код, который отправляется в функцию, выглядит следующим образом:

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

Если полный код uitextview содержит «? 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
    }

Я действительно обдумал этот.

0 голосов
/ 31 мая 2019

Вы можете разделить строку URL с "? U =" в качестве разделителя и получить второй элемент массива, используя эту функцию

В противном случае вы можете зациклить все свои элементы запроса и объединить их.

...