The string returned from php script is encoded.
I have a problem with an http post in delphi 2007 and Indy 10.6 towards a php script. The php script contains: header ("Content-Type: application / json; charset = UTF-8"); The Delphi part is this:
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
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.
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. TIdMultiPartFormDataStream
does encode text fields in quoted-printable format by default. =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.
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. So, you will have to either:
decode the QP encoding manually in your PHP script code.
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).
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.
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. 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.
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;