简体   繁体   English

Delphi Indy Post编码和PHP

[英]Delphi Indy Post Encoding and PHP

The string returned from php script is encoded. 从php脚本返回的字符串已编码。

I have a problem with an http post in delphi 2007 and Indy 10.6 towards a php script. 我在delphi 2007和Indy 10.6中针对php脚本的http发布有问题。 The php script contains: header ("Content-Type: application / json; charset = UTF-8"); php脚本包含:标头(“ Content-Type:应用程序/ json; charset = UTF-8”); The Delphi part is this: 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;

Response contains what should be saved in the mysql database whose varchar field is declared utf8-general-i both in the field and in the php echo, however, they return: = E0 = E8 = EC = F2 = F9 响应包含应保存在mysql数据库中的内容,该数据库的varchar字段在该字段和php echo中都声明为utf8-general-i,但是它们返回:= E0 = E8 = EC = F2 = F9

I tried to encode with UTF8Encode (dati.Values ​​[data.Names [cont]]), I tried to pass the UTF-8 charset to AddFormField but the string àèìòù is never returned. 我尝试使用UTF8Encode(dati.Values [data.Names [cont]])进行编码,我尝试将UTF-8字符集传递给AddFormField,但是从未返回字符串àèìòù。

What am I doing wrong? 我究竟做错了什么?

What you have shown looks like MIME's quoted-printable encoding, where non-ASCII/reserved byte octets are encoded in =HH hex format. 您显示的内容看起来像MIME的带quoted-printable编码,其中非ASCII /保留字节八位位组以=HH十六进制格式编码。 TIdMultiPartFormDataStream does encode text fields in quoted-printable format by default. 默认情况下, TIdMultiPartFormDataStream确实以带引号的格式编码文本字段。 =E0=E8=EC=F2=F9 is the QP-encoded form of the byte sequence $E0 $E8 $EC $F2 $F9 , which is the text 'àèìòù' encoded in the Latin-1 (ISO-8859-1) charset. =E0=E8=EC=F2=F9是字节序列$E0 $E8 $EC $F2 $F9的QP编码形式,它是用拉丁文1(ISO-8859-1)编码的文本'àèìòù' )字符集。

PHP does not support the Content-Transfer-Encoding header in multipart/form-data submissions ( see this ), so it does not automatically decode the QP encoding for you. PHP在multipart/form-data提交中不支持Content-Transfer-Encoding头( 请参阅参考资料 ),因此它不会自动为您解码QP编码。 So, you will have to either: 因此,您将必须:

  • decode the QP encoding manually in your PHP script code. 在您的PHP脚本代码中手动解码QP编码。

  • disable TIdMultipartFormDataStream from applying QP encoding, by setting the TIdFormDataField.ContentTransfer property to '8bit' instead of the default 'quoted-printable' (note that RFC 7578 deprecates the use of the Content-Transfer-Encoding header in multipart/form-data submissions over HTTP, but TIdMultipartFormDataStream has not been updated to account for that yet 1 ). 通过将TIdFormDataField.ContentTransfer属性设置为'8bit'而不是默认的'quoted-printable' (请注意, RFC 7578multipart/form-data提交中不建议使用Content-Transfer-Encoding标头),从而禁止TIdMultipartFormDataStream应用QP编码。通过HTTP,但TIdMultipartFormDataStream尚未更新以解决该问题1 )。

    1: Note - the TIdFormDataField.ContentTransfer property can be set to a blank string, which will disable the Content-Transfer-Encoding header from being sent, but it will also send the text as 7-bit US-ASCII, per RFC 2045 Section 6.1 , so don't use this option if you need to send text that contains non-ASCII characters. 1:注- 可以TIdFormDataField.ContentTransfer属性设置为空字符串,这将禁止发送Content-Transfer-Encoding标头,但根据RFC 2045节 ,它还将以7位US-ASCII格式发送文本6.1 ,因此如果您需要发送包含非ASCII字符的文本,请不要使用此选项。

Also, be aware that Delphi 2007 is not a Unicode enabled version of Delphi (ie, String = AnsiString ), which is why your text is being posted in Latin-1. 另外,请注意,Delphi 2007不是Unicode的Unicode版本(即String = AnsiString ),这就是为什么您的文本以Latin-1格式发布的原因。 In pre-Unicode versions, TIdMultiPartFormDataStream transmits AnsiString data as-is, so you are responsible for pre-encoding the posted AnsiString s in the desired byte encoding, such as UTF-8. 在Unicode之前的版本中, TIdMultiPartFormDataStream传输AnsiString数据,因此您负责以所需的字节编码(例如UTF-8)对发布的AnsiString进行预编码。

Try this instead: 尝试以下方法:

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM