Delphi Indy Post Кодирование и PHP - PullRequest
0 голосов
/ 15 мая 2019

Строка, возвращаемая из скрипта php, закодирована.

У меня проблема с постом http в delphi 2007 и Indy 10.6 в сторону php-скрипта. Скрипт php содержит: заголовок («Content-Type: application / json; charset = UTF-8»); Часть Delphi такова:

  data: = TStringList.Create;

  dati.Values ​​['id']: = '6';
  dati.Values ​​['name']: = 'àèìòù';

  lParams: = TIdMultiPartFormDataStream.Create;
  cont: = 0;
  try
    try
      url: = 'someurl';
      while cont <= data.Count-1 do
      begin
        lParams.AddFormField (data.Names [cont], data.Values ​​[data.Names [cont]]);
        Inc (cont);
      end;
      Response: = IdHTTP1.Post (url, lParams);
    except
      on E: Exception do
      Response: = E.ClassName + ':' + E.Message;
    end;
  finally
    lParams.Free;
    IdHTTP1.Disconnect;
  end;
  Result: = Response;

Ответ содержит то, что должно быть сохранено в базе данных mysql, чье поле varchar объявлено utf8-general-i как в поле, так и в php echo, однако они возвращают: = E0 = E8 = EC = F2 = F9

Я пытался кодировать с помощью UTF8Encode (dati.Values ​​[data.Names [cont]]), я пытался передать кодировку UTF-8 в AddFormField, но строка àèìòù никогда не возвращается.

Что я делаю не так?

1 Ответ

2 голосов
/ 15 мая 2019

То, что вы показали, выглядит как кодировка MIME quoted-printable, где не-ASCII / зарезервированные байтовые октеты кодируются в шестнадцатеричном формате =HH. TIdMultiPartFormDataStream по умолчанию кодирует текстовые поля в формате для печати в кавычках. =E0=E8=EC=F2=F9 является QP-кодированной формой последовательности байтов $E0 $E8 $EC $F2 $F9, которая представляет собой текст 'àèìòù', закодированный в кодировке Latin-1 (ISO-8859-1).

PHP не поддерживает заголовок Content-Transfer-Encoding в multipart/form-data сообщениях ( см. ), поэтому он не декодирует автоматически кодировку QP. Итак, вам придется либо:

  • декодируйте кодировку QP вручную в коде PHP-скрипта.

  • отключить TIdMultipartFormDataStream от применения кодировки QP, установив для свойства TIdFormDataField.ContentTransfer значение '8bit' вместо значения по умолчанию 'quoted-printable' (обратите внимание, что RFC 7578 не рекомендуется использовать * Заголовок 1027 * в multipart/form-data отправках по HTTP, но TIdMultipartFormDataStream еще не обновлен, чтобы учесть это 1 ).

    1: Примечание. Для свойства TIdFormDataField.ContentTransfer можно установить пустую строку, что отключит отправку заголовка Content-Transfer-Encoding, но при этом текст также будет отправлен как 7 -бит US-ASCII, согласно RFC 2045, раздел 6.1 , поэтому не используйте эту опцию, если вам нужно отправить текст, содержащий не-ASCII символы.

Также имейте в виду, что Delphi 2007 не является версией Delphi с поддержкой Юникода (т. Е. String = AnsiString), поэтому ваш текст публикуется на Latin-1. В версиях, предшествующих Unicode, TIdMultiPartFormDataStream передает AnsiString данных как есть, поэтому вы несете ответственность за предварительное кодирование отправленных AnsiString s в желаемом байтовом кодировании, например UTF-8.

Попробуйте вместо этого:

url := 'someurl';

try
  data := TStringList.Create;
  try
    data.Values ​​['id']: = '6';
    data.Values ​​['name'] := UTF8Encode('àèìòù'); // <-- omit UTF8Encode() in D2009+...

    lParams := TIdMultiPartFormDataStream.Create;
    try
      for cont := 0 to data.Count-1 do
      begin
        lParams.AddFormField(data.Names[cont], data.ValueFromIndex[cont], 'utf-8').ContentTransfer := '8bit';
      end;

      try
        Response := IdHTTP1.Post(url, lParams);
      finally
        IdHTTP1.Disconnect;
      end;
    finally
      lParams.Free;
    end;
  finally
    data.Free;
  end;
except
  on E: Exception do
    Response := E.ClassName + ':' + E.Message;
end;

Result := Response;
...