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

Delphi:TIdHTTP抛出异常时丢失编码如何解决?

解决TIdHTTP 400错误无法获取UTF-8响应体的问题

方案一:禁用HTTP协议错误异常

修改TIdHTTP的HTTPOptions属性,让它遇到400这类错误状态码时不抛出异常,而是正常返回响应内容,之后手动检查状态码即可:

var
  ssRequest, ssResponse: TStringStream;
begin
  // 初始化流...
  try
    // 禁用协议错误异常
    IdHTTP.HTTPOptions := IdHTTP.HTTPOptions + [hoNoProtocolErrorException];
    IdHTTP.Post(fullUrl, ssRequest, ssResponse);
    
    // 检查响应状态码
    if IdHTTP.Response.ResponseCode = 400 then
    begin
      // 设置正确的编码读取响应内容
      ssResponse.Position := 0;
      // 直接用UTF-8解码流内容
      var JsonStr := TEncoding.UTF8.GetString(ssResponse.Bytes);
      // 处理JSON数据...
    end;
  finally
    ssRequest.Free;
    ssResponse.Free;
  end;
end;

方案二:捕获异常并提取原始响应

如果需要保留异常捕获逻辑,可以在EIdHTTPProtocolException异常对象中提取完整响应数据,异常的Response属性包含原始响应字节,直接用UTF-8解码即可避免编码丢失:

var
  ssRequest, ssResponse: TStringStream;
begin
  // 初始化流...
  try
    IdHTTP.Post(fullUrl, ssRequest, ssResponse);
  except
    on E: EIdHTTPProtocolException do
    begin
      // 获取原始响应字节
      var RawResponse := E.Response.RawBytes;
      // 用UTF-8解码得到正确的JSON字符串
      var JsonStr := TEncoding.UTF8.GetString(RawResponse);
      // 处理JSON数据...
    end;
  end;
end;

关键说明

  • 原代码中ssResponse和IdHTTP.Response.ContentStream为空,是因为TIdHTTP抛出协议异常时,不会将响应内容写入指定的输出流,而是将数据暂存在异常对象的Response属性中。
  • 直接使用EIdHTTPProtocolException.ErrorMessage会丢失编码,因为TIdHTTP默认可能用系统编码解析响应,而不是UTF-8,所以必须从RawBytes提取原始字节后手动解码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:52:34