如何解决TIdHTTP调用ASP.NET接口返回JSON的重音字符乱码问题?
解决TIdHTTP调用ASP.NET服务器返回UTF-8重音字符乱码问题
问题分析
你遇到的乱码是因为服务器返回的UTF-8编码内容被TIdHTTP用系统默认的ANSI编码解析了。IdHTTP.Response.ContentEncoding用来处理内容压缩编码(如gzip),并不是字符编码,所以设置它无法解决字符乱码问题。
解决方案
以下两种方法都可以强制正确解析UTF-8编码的响应:
方法1:强制TIdHTTP使用UTF-8解析响应
通过设置Request.AcceptCharSet告知服务器优先返回UTF-8内容,同时手动指定响应的字符集为UTF-8:
Result := ''; IdHTTP := TIdHTTP.Create; try IdSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP); IdSSLIOHandlerSocketOpenSSL.SSLOptions.Mode := sslmClient; IdSSLIOHandlerSocketOpenSSL.SSLOptions.SSLVersions := [sslvTLSv1_2]; IdHTTP.IOHandler := IdSSLIOHandlerSocketOpenSSL; IdHTTP.HandleRedirects := True; // 关键设置:告诉服务器接受UTF-8编码 IdHTTP.Request.AcceptCharSet := 'utf-8'; url := 'testappUrl'; try IdHTTP.ConnectTimeout := 2000; IdHTTP.ReadTimeout := 4000; // 强制指定响应字符集为UTF-8 IdHTTP.Response.ContentType := 'application/json; charset=utf-8'; Response := IdHTTP.Get(url); ShowMessage(response); except on E:Exception do begin response := StringReplace(E.Message,#10,' ',[rfReplaceAll]); response := StringReplace(response,#13,' ',[rfReplaceAll]); response := '{"errormessage": "'+response+'"}'; end; end; Result := response; finally IdHTTP.Free; end;
方法2:获取原始字节流,手动转换为UTF-8字符串
绕开TIdHTTP的自动解码逻辑,直接处理原始字节,兼容性最好:
Result := ''; IdHTTP := TIdHTTP.Create; try IdSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP); IdSSLIOHandlerSocketOpenSSL.SSLOptions.Mode := sslmClient; IdSSLIOHandlerSocketOpenSSL.SSLOptions.SSLVersions := [sslvTLSv1_2]; IdHTTP.IOHandler := IdSSLIOHandlerSocketOpenSSL; IdHTTP.HandleRedirects := True; url := 'testappUrl'; try IdHTTP.ConnectTimeout := 2000; IdHTTP.ReadTimeout := 4000; // 用内存流接收原始响应字节 var Stream := TMemoryStream.Create; try IdHTTP.Get(url, Stream); Stream.Position := 0; // 将UTF-8字节转换为字符串 var Bytes := TBytes.Create; Stream.ReadBuffer(Bytes, Stream.Size); Response := TEncoding.UTF8.GetString(Bytes); ShowMessage(response); finally Stream.Free; end; except on E:Exception do begin response := StringReplace(E.Message,#10,' ',[rfReplaceAll]); response := StringReplace(response,#13,' ',[rfReplaceAll]); response := '{"errormessage": "'+response+'"}'; end; end; Result := response; finally IdHTTP.Free; end;
补充说明
- 如果服务器返回的
Content-Type头已包含charset=utf-8,TIdHTTP会自动用UTF-8解析,无需额外设置。乱码说明服务器可能未正确返回该头,或TIdHTTP默认使用了系统编码。 - 方法2是最稳妥的方案,无论服务器头是否正确,都能保证UTF-8内容被正确解析。
内容的提问来源于stack exchange,提问作者UnDiUdin
相关产品推荐
相关产品推荐

