delphi - Delphi XE8 idHttp Erromessage 文本编码错误
问题描述
我正在使用 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Ã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”
如何将返回的消息转换为普通字符串?
谢谢!
解决方案
您显示的结果 - - 是在 Latin-1/ISO-8859-1Megadott tranzakció azonosÃtóval már történt API hÃvás
中被误解的 UTF-8 编码形式。Megadott tranzakció azonosítóval már történt API hívás
这很可能意味着响应未在其Content-Type
标头中指定 UTF-8 字符集(因为您已Intercept
分配,您可以轻松地自己验证这一点),因此 Indy 将改为使用默认字符集。
原始 UTF-8 字节已被解码并丢失,然后您才能访问send_text
或中的响应数据error_message
。但是,由于 ISO-8859-1 基本上在字节值和 Unicode 代码点值之间具有 1:1 的关系,因此在这种特定情况下您可以尝试将ErrorMessage
'sChar
值原样复制到 a RawByteString(65001)
or 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
,然后您可以根据需要解码原始原始字节。只需确保启用属性中的hoNoProtocolErrorException
andhoWantProtocolErrorContent
标志,TIdHTTP.HTTPOptions
以便将任何错误响应存储在 中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;
...
推荐阅读
- c++ - Makefile:创建构建目录
- tensorflow - 为什么要求标签具有其他形状?
- java - 单击来自两个不同活动的两个单选按钮时,如何在新活动中显示文本?
- highcharts - 绘制布尔值时使用 max yAxis
- c# - 如何调试导致 this.Close() 在表单加载时挂起的包装类问题?
- php - in_array 函数是阻止代码注入/sql 注入的安全方法吗?
- sql - 将结果减少到仅基于单个字段具有超过 1 个唯一行的结果
- java - 使用 Java 14 发布 Gluon 移动应用程序
- sql - oracle sql中的空间数据-两点之间的距离
- spring-boot - 大写时无法获取 xmlelements 的值