2022-05-24

[PowerShell]解決PowerShell Invoke-RestMethod呼叫API亂碼問題

如題,但今天說明放後面,程式碼放前面:

function JsonEncoding{
    Param (
    [string]$json
    )
    # $utf8 = [System.Text.Encoding]::GetEncoding(65001)
    $iso88591 = [System.Text.Encoding]::GetEncoding(28591)
    $wrong_bytes = $iso88591.GetBytes($json)
    $right_string = [System.Text.Encoding]::UTF8.GetString($wrong_bytes)
    $right_string
}

老實說處理PowerShell亂碼的文章真多,並且Bruce也早早寫有一勞永逸的作法,讓cmd、PowerShell等等都能自動套用UTF-8編碼:https://blog.kkbruce.net/2021/10/solved-console-garbled-code-for-win10-win11.html?m=1&fbclid=IwAR21Umo0_S8I35y1i2xSsOAIUzDJnRfeqf_G2vEjYdd4ks1aZRnnj3kYoUI

黑大也有直接匯出txt讓文字編輯器幫我們編碼的作法:https://blog.darkthread.net/blog/ps-encoding

會寫這篇文章是因為也是工作上情勢所逼,公司電腦或Production環境常常有限網域、限權限、、、限限限 什麼都限的時候,不可能在每一台VM都裝Postman或隨意依賴系統管理員做事情,好在跳版機和公司筆電都是Win環境,那就可以好好利用PowerShell裡面的library啦!

首先呼叫一個回傳中文的API假設會得到:

Invoke-RestMethod "http://localhost:5000"
{
    "測試": "測試"
}

其實也可以用線上工具亂碼翻譯就好,但這樣有點遜,抽絲剝繭後才找到一位大陸網友2016的解法:https://www.codeprj.com/zh/blog/5332a01.html,才有最一開始的解碼工具。

有趣就在於要知道他是怎麼錯的。首先API回傳response給PowerShell,但PowerShell以為所收到的不是UTF-8編碼,所以我們得到的其實是ISO-8859-1編碼後的產物。此時需要先將結果倒置回去成bytes,再以UTF-8.GetString就完成囉!

下面是轉換的過程。

1. 以ISO-8859-1編碼倒置字串回bytes
$iso88591 = [System.Text.Encoding]::GetEncoding(28591)
$bytes = $iso88591.GetBytes("測試")
$bytes
230
184
172
232
169
166

2. 將bytes以UTF-8編碼
[System.Text.Encoding]::UTF8.GetString($bytes)
測試


沒有留言:

張貼留言