首页 > 解决方案 > 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”

如何将返回的消息转换为普通字符串?

谢谢!

标签: delphitextputidhttp

解决方案


您显示的结果 - - 是在 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,然后您可以根据需要解码原始原始字节。只需确保启用属性中的hoNoProtocolErrorExceptionandhoWantProtocolErrorContent标志,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;

...

推荐阅读