PowerShell 5.1用Invoke-RestMethod发送含NLS字符JSON的问题
解决方案
核心原因
你遇到的编码问题本质是对方API的编码处理逻辑不一致:硬编码的HMSHÃ¥ndbÞker是原字符串HMSHåndbøker经过「UTF-8编码→ISO-8859-1解码」后的结果,说明对方实际是按UTF-8解析请求体,但要求请求头声明为ISO-8859-1。
具体修正代码
修改JSON生成和请求发送部分,模拟正确的编码转换流程:
# 原逻辑:构造数据并生成JSON字符串 $larray = @{} $larray.Add("userName", $user.sn) # ... 其他数据构造逻辑 ... $data = @( @{"accessGranted"="true"; "applicationType"=$handbook1; "subapplicationId"="2"}, @{"accessGranted"="true"; "applicationType"=$handbook1; "subapplicationId"="4"}, @{"accessGranted"="true"; "applicationType"=$handbook1; "subapplicationId"="5"} ) $larray.Add("applicationAccess", $data) $json = ConvertTo-Json -Compress -Depth 4 -InputObject @($larray) # 关键步骤:将JSON字符串转成UTF-8字节,再用ISO-8859-1解码为字符串 $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($json) $encodedBody = [System.Text.Encoding]::GetEncoding(28591).GetString($utf8Bytes) # 修改请求头,指定编码为iso-8859-1 $url = "https://simployeramw.azure-api.net/ItasAPI-V2/importlogon" $lheaders = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $lheaders.Add("Content-Type", "application/json; charset=iso-8859-1") $lheaders.Add("X-ITAS-PersonIdentifierType", "EmployeeNumber") $lheaders.Add("X-ITAS-UnitIdType", "DepartmentCode") $lheaders.Add("Ocp-Apim-Subscription-Key", $CONST_AUTH_SKEY) $lheaders.Add("Authorization", "Bearer " + $token) # 发送请求,使用处理后的编码字符串作为Body $rc = Invoke-RestMethod $url -Method 'POST' -Headers $lheaders -Body $encodedBody
为什么之前的尝试无效
- 直接用
[Text.Encoding]::GetEncoding(28591)转换字符串:.NET字符串默认是UTF-16编码,转换为ISO-8859-1字节后,Invoke-RestMethod会默认将字节按UTF-8重新编码发送,导致二次编码混乱。 - 仅修改请求头:请求体依然是UTF-8编码的字符串,对方按ISO-8859-1解析时,特殊字符就会变成问号。
HtmlEncode():会将特殊字符转成HTML实体(如å→å),不符合对方API的解析要求。
备选方案(直接发送字节数组)
如果上面的方法无效,可以尝试直接发送UTF-8编码的字节数组,同时声明ISO-8859-1编码:
# 生成JSON字符串后,直接转成UTF-8字节数组 $bodyBytes = [System.Text.Encoding]::UTF8.GetBytes($json) # 发送请求时传入字节数组,指定ContentType $rc = Invoke-RestMethod $url -Method 'POST' -Headers $lheaders -Body $bodyBytes -ContentType "application/json; charset=iso-8859-1"
内容的提问来源于stack exchange,提问作者jmase
相关产品推荐
相关产品推荐

