You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 7+Indy 10 HTTP服务器UTF-8编码响应发送问题

在Delphi 7 + Indy 10 HTTP服务器中正确发送UTF-8编码的特殊字符响应

核心原因

Indy 10 与 Indy 9 的字符串处理逻辑差异显著:在Delphi 7(ANSI环境)下,Indy 10 的ContentText属性会自动将赋值的ANSI字符串转换为CharSet指定的编码。如果直接把UTF-8字节以ANSI字符串形式赋值,会触发重复编码转换,导致特殊字符乱码(比如ő变成无重音的o)。

正确解决方案

方案1:直接使用ANSI字符串(最简单可靠)

如果你的原始字符串是Delphi 7默认的ANSI格式(包含ő、á等特殊字符),只需设置CharSet为utf-8,Indy 10会自动完成ANSI到UTF-8的转换,同时在响应头的Content-Type中带上charset=utf-8:

procedure TYourForm.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  // 设置响应字符集为UTF-8
  AResponseInfo.CharSet := 'utf-8';
  // 直接赋值ANSI格式的字符串(包含ő、á等特殊字符)
  AResponseInfo.ContentText := '示例内容:ő、á、é、ű';
end;

方案2:处理已有的UTF-8字节流

如果你的数据已经是UTF-8编码的字节(比如从文件读取、接口获取的UTF-8数据),不要使用ContentText,改用ContentStream直接发送原始字节,避免Indy的自动转换:

procedure TYourForm.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  UTF8MemStream: TMemoryStream;
  UTF8Data: array of Byte;
begin
  // 示例:构造包含ő(UTF-8: $C5 $91)、á(UTF-8: $C3 $A1)的字节数组
  SetLength(UTF8Data, 14);
  UTF8Data[0] := $53; UTF8Data[1] := $61; UTF8Data[2] := $6D; // "Sam"
  UTF8Data[3] := $70; UTF8Data[4] := $6C; UTF8Data[5] := $65; // "ple"
  UTF8Data[6] := $3A; UTF8Data[7] := $20; // ": "
  UTF8Data[8] := $C5; UTF8Data[9] := $91; // ő
  UTF8Data[10] := $2C; UTF8Data[11] := $20; // ", "
  UTF8Data[12] := $C3; UTF8Data[13] := $A1; // á

  UTF8MemStream := TMemoryStream.Create;
  try
    UTF8MemStream.WriteBuffer(UTF8Data[0], Length(UTF8Data));
    UTF8MemStream.Position := 0;
    // 赋值流给响应,Indy会自动发送流中原始字节
    AResponseInfo.ContentStream := UTF8MemStream;
    // 明确指定字符集和Content-Type
    AResponseInfo.CharSet := 'utf-8';
    AResponseInfo.ContentType := 'text/plain; charset=utf-8';
    // 注意:不要手动释放UTF8MemStream,Indy会在响应发送完成后自动释放
  except
    UTF8MemStream.Free;
    raise;
  end;
end;

关键注意事项

  • 禁止将UTF-8字节以ANSI字符串形式赋值给ContentText,这会触发Indy的二次编码转换,必然导致乱码。
  • 若必须处理UTF-8格式的字符串(比如从其他UTF-8来源得到的字符串),可以先将其转换为ANSI字符串(使用TIdTextEncoding.UTF8.GetString()),再用方案1处理,但更推荐直接用方案2的流方式。
  • Indy 10在ANSI版本Delphi中没有DefStringEncoding属性,因此无法跳过ContentText的自动转换,流方式是最直接的替代方案。

内容的提问来源于stack exchange,提问作者Fenistil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 00:05:18