Используйте JSONKit и AFNetworking, чтобы сделать URL-запрос сложным объектом JSON

Я использую AFNetworking для входа в систему, и формат URL выглядит следующим образом:

http://xxx/mobile?function=login&req={username:xxx,password:xxx}

Итак, во-первых, я создал параметры, используя NSDictionary в NSDictionary, как показано ниже:

@{@"function" : @"login",
  @"req" : @{@"username" : @"xxx", @"password" : @"xxx"}}

Но запрос выходит неправильно

function=login&req[password]=xxx&req[username]=xxx

После этого я использовал JSONKit для упаковки параметра

NSDictionary *userInfo = @{@"userName" : [username URLEncodedString],
                           @"password" : [password URLEncodedString]};

NSDictionary *parameters = @{@"function" : @"login",
                           @"req" : [userInfo JSONString]};

И результаты кажутся похожими, но закодированы как "{}"

function=login&req=%7B%22userName%22%3A%22xxx%22%2C%22password%22%3A%22xxx%22%7D

Где я пошел не так? Как я могу это исправить? Большое спасибо!

1 ответ

Здесь есть пара вопросов.

  1. Вы, похоже, были обеспокоены процентным выходом в той части URL, которая выглядит следующим образом:

    function=login&req=%7B%22userName%22%3A%22xxx%22%2C%22password%22%3A%22xxx%22%7D
    

    Вы не должны беспокоиться об этом, потому что, когда сервер получает его, он автоматически преобразует это в:

    function=login&req={"userName":"xxx","password":"xxx"}
    

    Вы сообщаете, что сотрудник говорит вам, что проценты не нужны. Технически, он может быть прав (в этом случае вы можете уйти без побега процентов, если имя пользователя и пароль не имеют определенных зарезервированных символов, особенно +, & или же #(что может вызвать проблемы в URL), но согласно RFC относительно URL, все эти символы действительно должны быть экранированы в процентах. Кроме того, сервер автоматически удаляет этот параметр без процентов, так что вам не стоит беспокоиться о том, что запрос был сброшен в процентах. И, на самом деле, если вы хотите, чтобы этот интерфейс был надежным, клиенты iOS и Android действительно должны иметь процентные значения, подобные этим, которые вы добавляете в URL.

  2. Однако может показаться проблематичным то, что приведенный выше пример содержит двойные кавычки, тогда как вы предположили, что сервер ожидает что-то вроде:

    {username:xxx,password:xxx}
    

    Но это не действительно JSON. Действительный JSON будет:

    {"userName":"xxx","password":"xxx"}
    

    Итак, вы действительно уверены, что ваш веб-сервис хочет / нуждается в недопустимом JSON? Если вам абсолютно необходим недействительный JSON (и я был бы шокирован, если вы захотите это сделать), вам придется создать его вручную с помощью stringWithFormat, так как любой класс JSON, имеющий вес в соли, не сможет генерировать JSON без кавычек.

  3. Я бы не рекомендовал отправлять информацию об идентификаторе пользователя и пароле в URL. Это представляет угрозу безопасности, когда эта информация может быть легко взломана. Вы действительно должны поместить эти данные аутентификации в теле POST запрос, а не в URL GET запрос. (И, очевидно, вы хотите использовать HTTPS, а не HTTP.)

  4. Я также подвергаю сомнению, при всем уважении, подход смешивания x-www-form-urlencoded параметры стиля (для function а также req), но затем с помощью JSON для userName а также password, Как правило, вы бы использовали x-www-form-urlencoded запросы стиля или JSON, но очень любопытно объединить их вместе. Можно, но это немного странно.

Итак, суть в том, что вы можете создать URL, который вы описываете (делая это вручную с stringWithFormat), Я бы очень рекомендовал вам изменить дизайн своего веб-сервиса, чтобы POST запросы с деталями аутентификации в теле запроса; и (б) использовать либо JSON, либо x-www-form-urlencoded, но вы, вероятно, не хотите смешивать и сочетать.

Другие вопросы по тегам