Перейти к содержанию
Fire Monkey от А до Я
  • 0

Передача параметров (с русскими буквами) в UTF8 в NetHTTPClient.Post


Stalker

Вопрос

Hi All,

Delphi 10.3.3. На текущий момент VCL, дальше будет FMX для мобильных платформ.

Имеется Web-Сервис который вызывается через Post с передачей ему параметров в виде x-www-form-urlencoded. в теле запроса.

Параметры могут содержать русские буквы, поэтому они должны быть переданы в сервис в UTF8.

Вызовом этого сервиса занимается следующий код:

var
  ASource   :TStringList;
  cResponce :String;

begin

 ASource := TStringList.Create();

 ASource.Add('nParam1=1');
 ASource.Add('cParam2='+UTF8Encode(Edit1.Text));
 ASource.Add('cParam3='+UTF8Encode(Edit2.Text));
 ASource.Add('cParam4='+UTF8Encode(Edit3.Text));

 cResponce := NetHTTPClient1.Post('https://сайт/сервис', ASource).ContentAsString(TEncoding.UTF8);

 FreeAndNil(ASource);

Сам код работает нормально, сервис вызывается, данные возвращаются.

НО для передачи параметров в UTF8 приходится использовать функцию UTF8Encode, что приводит в Warning'у от Delphi:

Цитата

W1057 Implicit string cast from 'RawByteString' to 'string'

Вопрос: Как правильно организовать кодирование параметров в UTF8, что бы этого Warning'а не было ?

 

 

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Post(const AURL: string; const ASource: TStrings; const AResponseContent: TStream = nil;
      const AEncoding: TEncoding = nil;

 

cResponce := NetHTTPClient1.Post('https://сайт/сервис', ASource,nil, TEncoding.UTF8) .ContentAsString(TEncoding.UTF8);

и смотрим заголовок application/x-www-form-urlencoded; charset=???

Изменено пользователем Slym
Ссылка на комментарий
  • 0

Это я тоже пробовал. Или оно для другого или не работает как надо.

Кроме того, если Вы пройдете по коду NetHTTPClient1.Post внутрь исходников, то в

THTTPClient.Post в коде THTTPClient.CreateFormFromStings есть такая проверка:

  if AEncoding = nil then
    LEncoding := TEncoding.UTF8
  else
    LEncoding := AEncoding;

То есть  по умолчанию оно все равно будет UTF8 . Но как я уже сказал выше это не помогает.

Ссылка на комментарий
  • 0

а все-таки, заголовки какие передаются? мало ли что мы предполагаем. я помню, раскапывал код Post, так они там вообще не всегда прикладывались. Выбрал вариант, где они есть в явном виде и с тех пор использую его...

Ссылка на комментарий
  • 0

 

Вызывал Post и как 
NetHTTPClient1.Post('https://сайт/сервис', ASource,nil, TEncoding.UTF8) .ContentAsString(TEncoding.UTF8);

и как

NetHTTPClient1.Post('https://сайт/сервис', ASource) .ContentAsString(TEncoding.UTF8);

В обоих случаях заголовок, который приходит на сервер, одинаковый:

Цитата

HEADER: Connection=Keep-Alive
HEADER: Content-Type=application/x-www-form-urlencoded; charset=utf-8
HEADER: @HttpURI=/сервис
HEADER: @HttpMethod=POST
HEADER: Authorization=Basic d2dfVzqdUwQ==
HEADER: Host=сайт
HEADER: @HttpVersion=HTTP/1.1
HEADER: User-Agent=Embarcadero URI Client/1.0
HEADER: @MediaType=application/x-www-form-urlencoded
HEADER: Content-Length=109

 

Ссылка на комментарий
  • 0

Пример моего кода, который корректно отправляет/получает данные:
 

function Post(const ASession: TNetHTTPClient; const AUrl: string; const ASource: TStrings; const AIsURLEncode: Boolean): string;
var
  LResult: TStringStream;
begin
  Result := '';
  LResult := TStringStream.Create('', TEncoding.UTF8);
  try
    ASession.AcceptCharSet := 'utf-8';                                       
    if AIsURLEncode then
      ASession.Post(TNetEncoding.URL.Encode(AUrl, [], []), ASource, LResult)
    else
      ASession.Post(AUrl, ASource, LResult);
    Result := LResult.DataString;
  finally
    LResult.DisposeOf;
  end;
end;

 

Изменено пользователем Tumaso
Ссылка на комментарий
  • 0

Попробовал Ваш метод.

Сам сервис вызывается, но параметры в него все равно передаются в windows-1251, а не в UTF-8 и соответственно искомые данные не находятся. То есть все равно приходится использовать UTF8Encode. Так что Ваш вариант к сожалению тоже не помог и основной вопрос остается актуальным.

Суда по всему данные в Edit.Text в 1251, а перекодировкой параметров из ASource метод TNetHTTPClient.Post не занимается.

P.S. Пара  вопросов по вашему методу:

1. Почему DisposeOf, а не Free или FreeAndNil ?

2. Чем вариант возвращения данных запроса в LResult (в параметр) лучше, чем возвращаемый самим методом TNetHTTPClient.Post ?

Ссылка на комментарий
  • 0

что-то не сходится в показаниях

я тоже абсолютно корректно посылаю принимаю данные на win и android и все в правильной кодировке безо всяких ухищрений примерно аналогичным кодом

что-то важное вы скрываете...

 vResp := Http.Post(vURL, PostData, FResStream, FHeaders);

 

как версию рассматриваю еще кодирование 

TNetEncoding.URL.Encode(

 

хотя я например посылаю JSON в POST без кодирования и сервер все принимает нормально

 

 

Изменено пользователем krapotkin
Ссылка на комментарий
  • 0
16 часов назад, krapotkin сказал:

что-то не сходится в показаниях

я тоже абсолютно корректно посылаю принимаю данные на win и android и все в правильной кодировке безо всяких ухищрений примерно аналогичным кодом

что-то важное вы скрываете...

Что например я скрываю ?  Есть есть вопросы - задавайте. В атаче я прикрепил демку. Которая использует два варианта Post (мой и Tumaso).

Если ставишь галочку "Use UTF8Encode", данные (параметры запроса) в веб-сервис приходят в utf-8, если не ставишь то в windows-1251.

Дергал этот же сервис их Postman - там всегда параметры приходят в сервис в utf-8.

 

 

demo.rar

Ссылка на комментарий
  • 1

HTTPAnalyzer показывает:

POST / HTTP/1.1
Connection: Keep-Alive
Content-Type: application/x-www-form-urlencoded; charset=utf-8
User-Agent: Embarcadero URI Client/1.0
Host: www.yandex.ru
Content-Length: 148

nOwnerOrganizMode=1&cRegNumber=%D1%81-5%2F1&cBegRegDate=22.05.2029&cFIO=%D1%81%D0%B5%D1%80%D0%B3&cDocContent=%D0%B9%D1%86%D1%83qwe%D0%B9%D1%86%D1%83

Обилие %D0 - показывают что уходит UNICODE, а кодирование цифр и английского одним символом указывает что это UTF8... и заголовки этому соответствуют
Проблема на клиенте отсутствует... копай сервис
 

Ссылка на комментарий
  • 0
В 25.12.2019 в 04:58, Slym сказал:

Проблема на клиенте отсутствует... копай сервис

Большое Вам спасибо за подсказку, направили меня по верному пути.

Проблема оказалась действительно в сервисе, а точнее в том, как он видит значения параметров в зависимости от заголовка.

Если в HEADER указано Content-Type=application/x-www-form-urlencoded; charset=utf-8

то сервис делает автоматическую конвертацию из utf-8 в 1251 (эта кодировка базы сервиса)

А если указано Content-Type=application/x-www-form-urlencoded

то автоматическая конвертация не делается и ее должен сделать сам разработчик сервиса.

А так как раньше я тестировал свои сервисы только на Postman (а у него по умолчания второй вариант), то я всегда делал эту конвертацию сам. Отсюда и был баг неправильного значения параметра.

Ссылка на комментарий

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...