F#请求后端报UTF-8转UTF-16错误,Postman可正常请求求排查
问题分析与解决方案
首先,咱们从报错信息里抓核心:System.Text.DecoderFallbackException: Unable to translate bytes [E9] at index 629 from specified code page to Unicode,这说明后端接收到的请求体字节不是标准UTF-8编码,导致它在转成UTF-16字符串时失败。
为什么Postman能正常工作、printfn "%s" (payload |> string)也没问题?原因出在你当前的F#请求发送逻辑上:
- Postman默认会把JSON请求体以UTF-8编码转成字节发送,后端能正确解析;
printfn只是直接输出字符串内容,不涉及编码转字节的过程,所以看起来正常;- 你的代码里用
HttpRequestBody.TextRequest (payload |> string),这里的TextRequest在转字符串为字节时,可能用了系统默认编码(比如GBK、ISO-8859-1等),而不是UTF-8,导致后端收到的字节不符合UTF-8规范,解析报错。
修复方案
你有两种可靠的修改方式,都能确保请求体以UTF-8编码发送:
方案1:直接序列化JObject为UTF-8字节数组,使用BytesRequest
这种方式跳过字符串中转,直接生成标准UTF-8字节,最稳妥:
let postData url (payload:JObject) = // 直接将JObject序列化为UTF-8编码的字节数组 let utf8JsonBytes = System.Text.Encoding.UTF8.GetBytes(payload.ToString()) Http.RequestString ( url, headers = [HttpRequestHeaders.ContentType HttpContentTypes.Json], body = HttpRequestBody.BytesRequest utf8JsonBytes )
方案2:确保TextRequest使用UTF-8编码(如果FSharp.Data支持的话)
如果你的FSharp.Data版本允许指定TextRequest的编码,可以这样修改(部分版本的TextRequest有重载支持传入编码):
let postData url (payload:JObject) = Http.RequestString ( url, headers = [HttpRequestHeaders.ContentType HttpContentTypes.Json], body = HttpRequestBody.TextRequest (payload |> string, System.Text.Encoding.UTF8) )
为什么原来的写法会出问题?
当你把JObject转成string后,TextRequest默认会用当前系统的ANSI编码来把字符串转成字节。如果你的系统默认编码不是UTF-8(比如中文系统常用的GBK),那么包含非ASCII字符(比如中文、特殊符号)的JSON字符串,转成的字节就不是UTF-8格式,后端用UTF-8解析自然会失败。
内容的提问来源于stack exchange,提问作者Jacek Dominiak
相关产品推荐
相关产品推荐

