【问题标题】:Powershell ConvertFrom-Json Encoding Special Characters IssuePowershell ConvertFrom-Json 编码特殊字符问题
【发布时间】:2018-10-28 15:40:58
【问题描述】:

我的 powershell 脚本中有这段代码,但它在特殊字符部分上表现不佳。

 $request = 'http://151.80.109.18:8082/vrageremote/v1/session/players'
 $a = Invoke-WebRequest -ContentType "application/json; charset=utf-8" $request |
 ConvertFrom-Json    |
 Select -expand Data |
 Select -expand players |
 Select displayName, factionTag | Out-file "$scriptPath\getFactionTag.txt"

在我的输出文件中,我只得到 '????'对于任何特殊字符。有谁知道如何让它在我的输出文件中显示特殊字符?

【问题讨论】:

    标签: powershell character-encoding invoke-webrequest


    【解决方案1】:

    Peter Schneider's helpful answerNas' helpful answer 都解决了您的方法存在的一个问题:您需要:

    • 或者:访问Invoke-WebRequest 返回的响应对象上的.Content 属性以获取返回的实际数据(作为JSON 字符串),然后您可以将其传递给ConvertFrom-Json

    • 或:改用Invoke-RestMethod,它直接返回数据并将其解析为自定义对象,因此您可以直接使用这些对象,而无需ConvertTo-Json;但是,对于字符编码问题,例如在这种情况下,这 不是 一个选项,因为需要对 JSON 字符串进行显式重新编码 - 见下文。

    但是,您仍然有一个字符编码问题,因为在响应中缺少charset 信息 header,PowerShell 将返回为ISO-8859-1-encoded 的 UTF-8 编码 JSON 字符串解释(自 PowerShell 7.0 起仍适用)。

    有两种可能的解决方案:

    • 最好将 Web 服务修改为在响应标头的 ContenType 字段中包含 charset=utf-8

    • 如果您不能这样做,您必须明确地重新编码收到的字符串以纠正字符编码的误解。

    这是后者的实现:

    $request = 'http://151.80.109.18:8082/vrageremote/v1/session/players'
    $a = Invoke-WebRequest -ContentType "application/json; charset=utf-8" $request
    
    # $a.Content now contains the *misinterpreted* JSON string, so we must 
    # obtain its byte representation and re-interpret the bytes as UTF-8.
    # Encoding 28591 represents the ISO-8859-1 encoding - see https://docs.microsoft.com/en-us/windows/desktop/Intl/code-page-identifiers
    $jsonCorrected = [Text.Encoding]::UTF8.GetString(
      [Text.Encoding]::GetEncoding(28591).GetBytes($a.Content)
    )
    
    # Now process the reinterpreted string.
    $jsonCorrected |
      ConvertFrom-Json    |
      Select -expand Data |
      Select -expand players |
      Select displayName, factionTag | Out-file "$scriptPath\getFactionTag.txt"
    

    【讨论】:

      【解决方案2】:

      如果你只需要json数据而不需要ParsedHtmlHeadersInvoke-WebRequest返回的其他对象,请使用Invoke-RestMethod

      $request = 'http://151.80.109.18:8082/vrageremote/v1/session/players'
      $a = Invoke-RestMethod -ContentType "application/json; charset=utf-8" $request |
      Select -expand Data |
      Select -expand players |
      Select displayName, factionTag | Out-file "$scriptPath\getFactionTag.txt"
      

      【讨论】:

      • 与上面的结果相同,这摆脱了'????'字符,但现在我留下了很多“D”。就像 'УРА' 变成 'УРÐ'
      • 一般来说这是有用的建议,但这里的问题是字符编码之一,因此需要在进一步处理之前对接收到的 string 数据执行显式重新编码,因此在这种特殊情况下,需要使用 Invoke-WebRequest 响应的 .Content 属性。
      • 我在 Invoke-RestMethod 调用的标头对象中尝试 -ContentType "application/json; charset=utf-8" 但它不起作用,将它作为单独的参数传递给 `Invoke- RestMethod -ContentType "application/json; charset=utf-8" 完美运行
      【解决方案3】:

      尝试将.Content属性的值转换为JSON:

      $request = 'http://151.80.109.18:8082/vrageremote/v1/session/players'
      $a = Invoke-WebRequest -ContentType "application/json; charset=utf-8" $request
      
      ($a.Content | convertfrom-json).Data.Players | select DisplayName,FactionTag | Out-file "$scriptPath\getFactionTag.txt" -Encoding Default
      

      【讨论】:

      • 这去掉了'????'字符,但现在我留下了很多“D”。就像 'УРА' 变成 'УРÐ'
      猜你喜欢
      • 2018-05-26
      • 1970-01-01
      • 2015-06-01
      • 2017-06-03
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      • 2020-09-13
      • 1970-01-01
      相关资源
      最近更新 更多