Delphi XE8 idHttp Erromessage 文本编码错误
Delphi XE8 idHttp Erromessage text coding is wrong
我正在使用 Delphi XE8,我正在通过 idHttp 发送 PUT 消息。
Http.Request.CustomHeaders.Clear;
Http.Request.BasicAuthentication := false;
http.Request.Method := 'PUT';
Http.Request.Accept := '*/*';
Http.Request.ContentType := 'application/json';
http.Request.CustomHeaders.AddValue('apiKey','T_API23207_169');
http.Request.CustomHeaders.AddValue('transactionId','20200924_015');
http.Request.CustomHeaders.AddValue('usziID','1');
Http.Request.AcceptEncoding := '*';
http.Request.CharSet := 'utf-8';
kuldes_header.Text := http.Request.CustomHeaders.Text;
http.Intercept := IdLogEvent1;
IdLogEvent1.Active := true;
jsonToSend := TStringStream.create(json_adat.Text,system.sysUtils.TEncoding.UTF8);
kuldes_body.Lines.LoadFromStream(jsonToSend);
try
try
send_text := http.Put('http://10.109.132.24:8090/rest/usziIroda/1',jsonToSend);
resp := http.ResponseText;
code := http.ResponseCode;
jsonToSend.Position := 0;
except
on E: EIdHTTPProtocolException do
begin
code := e.ErrorCode;
error_message := e.ErrorMessage;
end;
end;
hiba_kod.Lines.Add(IntToStr(code));
valasz_uzenet.Text := send_text;
hiba_uzenet.Text := error_message; enter code here
返回的错误信息有奇怪的字符:
"Megadott tranzakció azonosóval már történt API hávás"
但应该是这样的:
"Megadott tranzakció azonosítóval már történt API hívás"
如何将返回的消息转换为普通字符串?
谢谢!
您显示的结果 - Megadott tranzakció azonosÃtóval már történt API hÃvás
- 是 Megadott tranzakció azonosítóval már történt API hívás
的 UTF-8 编码形式在 Latin-1/ISO-8859-1 中被误解了。这很可能意味着响应没有在其 Content-Type
header 中指定 UTF-8 字符集(因为您分配了 Intercept
,您可以轻松地自己验证这一点),所以 Indy将退回到默认字符集。
在您可以访问 send_text
或 error_message
中的响应数据之前,原始 UTF-8 字节已被解码并丢失。但是,由于 ISO-8859-1 在字节值和 Unicode 代码点值之间基本上具有 1:1 关系,因此在这种特定情况下您可以尝试复制 ErrorMessage
的 Char
值as-is 到 RawByteString(65001)
或 UTF8String
,然后让 RTL 将其解码为 UTF-8 回到正确的 UTF-16 (Unicode)String
,例如:
function DecodeISO88591AsUTF8(const S: string): string;
var
utf8: UTF8String;
I: Integer;
begin
SetLength(utf8, Length(S));
for I := Low(S) to High(S) do
utf8[I] := AnsiChar(S[I]);
Result := string(utf8);
end;
...
error_message := e.ErrorMessage;
//if not TextIsSame(http.Response.CharSet, 'utf-8') then
if TextIsSame(http.Response.CharSet, 'ISO-8859-1') then
error_message := DecodeISO88591AsUTF8(error_message);
或者,您可以改为调用 TIdHTTP.Put()
的重载版本来填充响应 TStream
而不是返回已解码的 String
,然后您可以解码原始原始字节你要。只要确保在 TIdHTTP.HTTPOptions
属性 中启用 hoNoProtocolErrorException
和 hoWantProtocolErrorContent
标志,以便任何错误响应都存储在 TStream
中,那么你就不会需要 try/except
来单独处理 EIdHTTPProtocolException
。
http.HTTPOptions := http.HTTPOptions + [hoNoProtocolErrorException, hoWantProtocolErrorContent];
...
RespStrm := TMemoryStream.Create;
try
http.Put('http://10.109.132.24:8090/rest/usziIroda/1', jsonToSend, RespStrm);
resp := http.ResponseText;
code := http.ResponseCode;
jsonToSend.Position := 0;
RespStrm.Position := 0;
if (code div 100) = 2 then
begin
send_text := decode RespStrm as needed...;
end else
begin
error_message := decode RespStrm as needed...;
end;
finally
RespStrm.Free;
end;
...
我正在使用 Delphi XE8,我正在通过 idHttp 发送 PUT 消息。
Http.Request.CustomHeaders.Clear;
Http.Request.BasicAuthentication := false;
http.Request.Method := 'PUT';
Http.Request.Accept := '*/*';
Http.Request.ContentType := 'application/json';
http.Request.CustomHeaders.AddValue('apiKey','T_API23207_169');
http.Request.CustomHeaders.AddValue('transactionId','20200924_015');
http.Request.CustomHeaders.AddValue('usziID','1');
Http.Request.AcceptEncoding := '*';
http.Request.CharSet := 'utf-8';
kuldes_header.Text := http.Request.CustomHeaders.Text;
http.Intercept := IdLogEvent1;
IdLogEvent1.Active := true;
jsonToSend := TStringStream.create(json_adat.Text,system.sysUtils.TEncoding.UTF8);
kuldes_body.Lines.LoadFromStream(jsonToSend);
try
try
send_text := http.Put('http://10.109.132.24:8090/rest/usziIroda/1',jsonToSend);
resp := http.ResponseText;
code := http.ResponseCode;
jsonToSend.Position := 0;
except
on E: EIdHTTPProtocolException do
begin
code := e.ErrorCode;
error_message := e.ErrorMessage;
end;
end;
hiba_kod.Lines.Add(IntToStr(code));
valasz_uzenet.Text := send_text;
hiba_uzenet.Text := error_message; enter code here
返回的错误信息有奇怪的字符: "Megadott tranzakció azonosóval már történt API hávás"
但应该是这样的: "Megadott tranzakció azonosítóval már történt API hívás"
如何将返回的消息转换为普通字符串?
谢谢!
您显示的结果 - Megadott tranzakció azonosÃtóval már történt API hÃvás
- 是 Megadott tranzakció azonosítóval már történt API hívás
的 UTF-8 编码形式在 Latin-1/ISO-8859-1 中被误解了。这很可能意味着响应没有在其 Content-Type
header 中指定 UTF-8 字符集(因为您分配了 Intercept
,您可以轻松地自己验证这一点),所以 Indy将退回到默认字符集。
在您可以访问 send_text
或 error_message
中的响应数据之前,原始 UTF-8 字节已被解码并丢失。但是,由于 ISO-8859-1 在字节值和 Unicode 代码点值之间基本上具有 1:1 关系,因此在这种特定情况下您可以尝试复制 ErrorMessage
的 Char
值as-is 到 RawByteString(65001)
或 UTF8String
,然后让 RTL 将其解码为 UTF-8 回到正确的 UTF-16 (Unicode)String
,例如:
function DecodeISO88591AsUTF8(const S: string): string;
var
utf8: UTF8String;
I: Integer;
begin
SetLength(utf8, Length(S));
for I := Low(S) to High(S) do
utf8[I] := AnsiChar(S[I]);
Result := string(utf8);
end;
...
error_message := e.ErrorMessage;
//if not TextIsSame(http.Response.CharSet, 'utf-8') then
if TextIsSame(http.Response.CharSet, 'ISO-8859-1') then
error_message := DecodeISO88591AsUTF8(error_message);
或者,您可以改为调用 TIdHTTP.Put()
的重载版本来填充响应 TStream
而不是返回已解码的 String
,然后您可以解码原始原始字节你要。只要确保在 TIdHTTP.HTTPOptions
属性 中启用 hoNoProtocolErrorException
和 hoWantProtocolErrorContent
标志,以便任何错误响应都存储在 TStream
中,那么你就不会需要 try/except
来单独处理 EIdHTTPProtocolException
。
http.HTTPOptions := http.HTTPOptions + [hoNoProtocolErrorException, hoWantProtocolErrorContent];
...
RespStrm := TMemoryStream.Create;
try
http.Put('http://10.109.132.24:8090/rest/usziIroda/1', jsonToSend, RespStrm);
resp := http.ResponseText;
code := http.ResponseCode;
jsonToSend.Position := 0;
RespStrm.Position := 0;
if (code div 100) = 2 then
begin
send_text := decode RespStrm as needed...;
end else
begin
error_message := decode RespStrm as needed...;
end;
finally
RespStrm.Free;
end;
...