Swift: невозможно добавить строку формата .prettyPrinted в forHTTPHeaderField

Продолжая от этого вопроса,

Я пытаюсь преобразовать [String : Any] в String, а затем передать это String в forHTTPHeaderField.

Попытка 1: без Pretty

let encoder = JSONEncoder()

if let json = try? encoder.encode(jsonDict) {
   convertedString = String(data: json, encoding: .utf8)!
}

print("JsonStringFormat     ", convertedString )

let url = NSURL(string: getMenuURL)
let request = NSMutableURLRequest(url: url! as URL)
request.setValue(convertedString, forHTTPHeaderField: "SessionInfo")

print("\nHEADer__reQQ__    ", request.allHTTPHeaderFields)

ВЫВОД:

JsonStringFormat      {"Token":"96FFC5B994514B3D","UICulture":"en-CA ","LanguageCode":"ENG","CompanyID":"QAP","IMEINo":"1jzBG3TSrMzj\/tKihlEv8g=="}
HEADer__reQQ__     ["SessionInfo": "{\"Token\":\"96FFC5B994514B3D\",\"LanguageCode\":\"ENG\",\"UICulture\":\"en-CA \",\"CompanyID\":\"QAP\",\"IMEINo\":\"1jzBG3TSrMzj\\/tKihlEv8g==\"}"]

Попытка 2: с напечатанным .pretty

let encoder = JSONEncoder()

// ADDING PRETTY FORMAT
encoder.outputFormatting = .prettyPrinted

if let json = try? encoder.encode(jsonDict) {
   convertedString = String(data: json, encoding: .utf8)!
}

print("PrettyJsonStringFormat     ", convertedString )

let url = NSURL(string: getMenuURL)
let request = NSMutableURLRequest(url: url! as URL)
request.setValue(convertedString, forHTTPHeaderField: "SessionInfo")

print("\nPrettyHeader__    ", request.allHTTPHeaderFields)

ВЫВОД:

PrettyJsonStringFormat      {
  "Token" : "70E277954143414A",
  "UICulture" : "en-CA ",
  "LanguageCode" : "ENG",
  "CompanyID" : "QAP",
  "IMEINo" : "1jzBG3TSrMzj\/tKihlEv8g=="
}

PrettyHeader__    [:]

Если я выберу Попытку 1, к этому значению будет добавлено BackSlash \. Чтобы избежать этого, я использую Попытку 2, [Pretty Printed] .

Я не знаю, почему request.allHTTPHeaderFields нет добавленных значений заголовка.

Пожалуйста, направь меня.


person McDonal_11    schedule 14.06.2019    source источник
comment
Почему prettyPrinted? Сервер не заботится о читаемости.   -  person vadian    schedule 14.06.2019
comment
В моем предыдущем вопросе stackoverflow.com/questions/56582434/ на снимке экрана Postman, я дал значение для ключа SessionInfo в формате JSON . Я пробовал то же самое в forHTTPHeaderField в Swift. Он принимает только в формате String. Итак, я преобразовал в строку, а затем передал значение в forHTTPHeaderField. Я получил ошибку в ответ. Теперь я пытаюсь напечатать allHTTPHeaderFields , напечатанная строка содержит \ . Я думал, что это \ может быть проблемой. Поэтому я выбираю красиво напечатанный .   -  person McDonal_11    schedule 17.06.2019


Ответы (2)


Это потому, что convertedString в Attempt2 имеет несколько строк.

RFC говорит, что значение поля заголовка, состоящее из нескольких строк, устарело.

Исторически сложилось так, что значения поля заголовка HTTP можно было расширить на несколько строк, предваряя каждую дополнительную строку по крайней мере одним пробелом или горизонтальной табуляцией (obs-fold). Эта спецификация осуждает такое свертывание строк, за исключением медиа-типа message/http (раздел 8.3.1). Отправитель НЕ ДОЛЖЕН генерировать сообщение, которое включает свертывание строк (т. е. имеет какое-либо значение поля, содержащее совпадение с правилом obs-fold), если только сообщение не предназначено для упаковки в тип носителя message/http.

И setValue(_:forHTTPHeaderField:), кажется, игнорирует такие значения.

// This does nothing. Just ignoring the value "A\nB"
request.setValue("A\nB", forHTTPHeaderField: "C")

Кроме того, обратная косая черта в Attempt1 не вызовет проблем. Сервер, получивший запрос, правильно обработает значение.

person pompopo    schedule 14.06.2019
comment
Спасибо @pompopo, не могли бы вы помочь мне с этим? stackoverflow.com/questions/56582434/ - person McDonal_11; 14.06.2019
comment
Этот вопрос до сих пор не решен? Кажется, у вас уже есть допустимое значение String. - person pompopo; 14.06.2019
comment
Если у меня есть действительная преобразованная строка, я могу получить некоторое значение в data из предыдущего вопроса. - person McDonal_11; 14.06.2019
comment
Мой запрос: я нажимаю GET API с заголовками и ответом в виде изображения. Скриншот Postman, который я приложил в предыдущем вопросе. Но с помощью Swift я не смог этого добиться. Можете направить меня?? - person McDonal_11; 14.06.2019
comment
Проблема: в Postman я могу добавить заголовок в формате JSON. Но в Swift я не мог этого сделать. Итак, я пытаюсь преобразовать этот формат JSON в строку. Хотя я преобразовал в String, результат API - Error - person McDonal_11; 14.06.2019
comment
API-сервер находится под вашим контролем? Если это так, вы можете просмотреть разницу запросов, почтальона и Swift. - person pompopo; 14.06.2019
comment
Так грустно... у меня нет этого контроля. - person McDonal_11; 14.06.2019
comment
Какую ошибку вы получаете сейчас? Это ошибка апи? Покажите свой текущий allHTTPHeaderFields . Если он имеет допустимые значения, может возникнуть другая проблема. - person pompopo; 14.06.2019

Вы должны проверить этот ответ по этой ссылке

Ваше понимание стандарта верное. Раньше многострочные значения заголовков поддерживались в RFC 2616. Эта функция была известна как «Складывание строк»:

Значения полей заголовка HTTP/1.1 могут быть объединены в несколько строк, если строка продолжения начинается с пробела или горизонтальной табуляции. Все линейные пробелы, включая фолдинг, имеют ту же семантику, что и SP. Получатель МОЖЕТ заменить любой линейный пробел одним SP перед интерпретацией значения поля или пересылкой сообщения вниз по течению.

person dimohamdy    schedule 15.06.2019