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
相关产品推荐
相关产品推荐

