eagleye

旧版本 PowerShell 中文字符处理完整解决方案

旧版本 PowerShell 中文字符处理完整解决方案文档

一、问题背景

在低版本 PowerShell(如 2.0/3.0)中,由于不支持-ResponseHeadersVariable等新参数,或编码处理机制不完善,发送 HTTP 请求时可能出现中文字符乱码(如响应内容含中文、错误信息乱码)。本文提供兼容旧版 PowerShell 的中文字符处理方案,涵盖Invoke-WebRequest改进脚本、curl.exe替代方案及.NET WebClient兜底方法,确保不同版本环境下中文字符正确显示与解析。

二、核心问题分析

低版本 PowerShell 中文字符乱码的核心原因:

1. 参数支持缺失:如不支持-ResponseHeadersVariable,无法直接获取响应头中的编码信息;

2. 编码处理机制弱:默认编码与服务器返回编码(如 UTF-8)不匹配,且无自动转换逻辑;

3. 错误信息解析难:错误响应内容可能以字节数组形式返回,需手动解码才能显示中文。

三、兼容旧版 PowerShell 的解决方案

方案 1:改进版Invoke-WebRequest(适用于 PowerShell 3.0+)

针对低版本 PowerShell 调整Invoke-WebRequest脚本,通过手动提取响应头编码、字节数组转字符串等步骤,确保中文字符正确处理。

脚本代码与关键步骤:

# 1. 设置控制台输出编码为 UTF-8(核心步骤,避免显示乱码)

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

$OutputEncoding = [System.Text.Encoding]::UTF8

$token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzUxNzE3OTIwLCJpYXQiOjE3NTE3MDM1MjAsImp0aSI6IjUxMzlhYjA4Njk2ODQ2ZmZhMjcyOGUzODdjZjMzYzRkIiwidXNlcl9pZCI6IjdjODQxN2JiLTliYTMtNGVjMC04NjZiLWNhOTMyNDg0ODY5MyIsImF1ZCI6WyJ3ZWItYXBwIiwibW9iaWxlLWFwcCJdLCJpc3MiOiJzYWZlLXNlbnRyeS1hdXRoLXNlcnZpY2UifQ.G6IXXX_9NSm9tkg6v0X1BIPThQVwLCEjLzUjV8KkBp0"

try {

# 2. 发送请求(兼容旧版参数)

$response = Invoke-WebRequest -Uri "http://127.0.0.1:8000/api/auth/diagnostic/" `

-Headers @{

"Authorization" = "Bearer $token"

"Content-Type" = "application/json; charset=utf-8" # 声明请求编码

"Accept-Charset" = "utf-8" # 要求响应编码

} `

-Method Get

# 3. 手动处理响应内容编码

$content = $response.Content

# 从响应头提取编码(默认 UTF-8)

$charset = "utf-8"

$contentType = $response.Headers["Content-Type"] # 兼容旧版获取响应头方式

if ($contentType -and $contentType -match 'charset=([\w-]+)') {

$charset = $matches[1] # 适配服务器返回的实际编码(如 GBK)

}

# 若内容为字节数组(非字符串),转换为指定编码的字符串

if ($content -isnot [string]) {

$encoding = [System.Text.Encoding]::GetEncoding($charset)

$content = $encoding.GetString($content)

}

# 4. 显示响应内容(支持中文)

Write-Host "状态码: $($response.StatusCode)" -ForegroundColor Green

Write-Host "响应内容:"

# 尝试解析 JSON(兼容非 JSON 响应)

try {

$jsonResponse = $content | ConvertFrom-Json

$jsonResponse | Format-List # 格式化显示 JSON

}

catch {

Write-Host $content # 非 JSON 直接输出

}

}

catch {

# 5. 错误处理(支持中文错误信息)

Write-Host "请求失败: $($_.Exception.Message)" -ForegroundColor Red

# 解析错误详情(处理字节数组乱码)

$errorDetails = $_.ErrorDetails ?? $_.Exception.Response # 兼容旧版错误对象

if ($errorDetails) {

$errorContent = $errorDetails.Message ?? $errorDetails.StatusDescription

if ($errorContent -isnot [string]) {

try {

$errorContent = [System.Text.Encoding]::UTF8.GetString($errorContent) # 手动解码

}

catch {

$errorContent = "无法解析的错误内容"

}

}

Write-Host "错误详情: $errorContent" -ForegroundColor Red

}

else {

Write-Host "无额外错误信息" -ForegroundColor Red

}

# 显示状态码(兼容旧版)

$statusCode = $_.Exception.Response?.StatusCode.value__ ?? $_.Exception.Status

if ($statusCode) {

Write-Host "状态码: $statusCode" -ForegroundColor Red

}

}

方案 2:原生curl.exe(推荐,兼容所有版本)

curl.exe无需依赖 PowerShell 新参数,直接原样发送请求并处理编码,是旧版 PowerShell 中最可靠的中文字符处理方案。

脚本代码与说明:

# 1. 设置控制台输出编码为 UTF-8(确保显示正确)

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

$OutputEncoding = [System.Text.Encoding]::UTF8

$token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzUxNzE3OTIwLCJpYXQiOjE3NTE3MDM1MjAsImp0aSI6IjUxMzlhYjA4Njk2ODQ2ZmZhMjcyOGUzODdjZjMzYzRkIiwidXNlcl9pZCI6IjdjODQxN2JiLTliYTMtNGVjMC04NjZiLWNhOTMyNDg0ODY5MyIsImF1ZCI6WyJ3ZWItYXBwIiwibW9iaWxlLWFwcCJdLCJpc3MiOiJzYWZlLXNlbnRyeS1hdXRoLXNlcnZpY2UifQ.G6IXXX_9NSm9tkg6v0X1BIPThQVwLCEjLzUjV8KkBp0"

# 2. 生成临时文件保存响应(避免控制台编码干扰)

$tempFile = [System.IO.Path]::GetTempFileName()

try {

# 3. 使用 curl.exe 发送请求(显式指定编码)

curl.exe -s -o $tempFile `

-H "Authorization: Bearer $token" `

-H "Content-Type: application/json; charset=utf-8" `

-H "Accept-Charset: utf-8" `

"http://127.0.0.1:8000/api/auth/diagnostic/"

# 4. 读取临时文件(使用 UTF-8 编码)

$content = Get-Content -Path $tempFile -Encoding UTF8

# 5. 显示响应内容(支持中文)

Write-Host "响应内容:"

try {

$jsonResponse = $content | ConvertFrom-Json

$jsonResponse | Format-List # 格式化 JSON

}

catch {

Write-Host $content # 非 JSON 直接输出

}

}

catch {

# 6. 错误处理

Write-Host "请求失败: $($_.Exception.Message)" -ForegroundColor Red

}

finally {

# 7. 清理临时文件(确保无残留)

if (Test-Path $tempFile) {

Remove-Item $tempFile -Force

}

}

方案 3:.NETWebClient类(兜底方案,兼容所有版本)

Invoke-WebRequest和curl.exe均不可用,可通过 .NET 内置的WebClient类发送请求,兼容所有 PowerShell 版本。

脚本代码与说明:

# 1. 设置控制台输出编码为 UTF-8

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

$OutputEncoding = [System.Text.Encoding]::UTF8

$token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzUxNzE3OTIwLCJpYXQiOjE3NTE3MDM1MjAsImp0aSI6IjUxMzlhYjA4Njk2ODQ2ZmZhMjcyOGUzODdjZjMzYzRkIiwidXNlcl9pZCI6IjdjODQxN2JiLTliYTMtNGVjMC04NjZiLWNhOTMyNDg0ODY5MyIsImF1ZCI6WyJ3ZWItYXBwIiwibW9iaWxlLWFwcCJdLCJpc3MiOiJzYWZlLXNlbnRyeS1hdXRoLXNlcnZpY2UifQ.G6IXXX_9NSm9tkg6v0X1BIPThQVwLCEjLzUjV8KkBp0"

try {

# 2. 初始化 WebClient(设置编码)

$webClient = New-Object System.Net.WebClient

$webClient.Encoding = [System.Text.Encoding]::UTF8 # 强制使用 UTF-8 编码

$webClient.Headers.Add("Authorization", "Bearer $token")

$webClient.Headers.Add("Content-Type", "application/json; charset=utf-8")

$webClient.Headers.Add("Accept-Charset", "utf-8")

# 3. 发送请求并获取响应

$response = $webClient.DownloadString("http://127.0.0.1:8000/api/auth/diagnostic/")

# 4. 显示响应内容(支持中文)

Write-Host "响应内容:"

try {

$jsonResponse = $response | ConvertFrom-Json

$jsonResponse | Format-List # 格式化 JSON

}

catch {

Write-Host $response # 非 JSON 直接输出

}

}

catch {

# 5. 错误处理(解析错误流)

Write-Host "请求失败: $($_.Exception.Message)" -ForegroundColor Red

if ($_.Exception.Response) {

$errorStream = $_.Exception.Response.GetResponseStream()

$errorStream.Position = 0 # 重置流位置

$reader = New-Object System.IO.StreamReader($errorStream)

$errorContent = $reader.ReadToEnd() # 读取错误内容

$reader.Close()

Write-Host "错误详情: $errorContent" -ForegroundColor Red

}

}

四、兼容性指南与版本推荐

PowerShell 版本

推荐方案

原因

5.0 及以上

改进的Invoke-WebRequest

支持新参数,编码处理更便捷

3.0-4.0

基础Invoke-WebRequest

需手动提取响应头编码,但无需额外工具

2.0 及以下

curl.exe或.NET WebClient

curl.exe最可靠;WebClient作为兜底,兼容所有环境

五、检查 PowerShell 版本

运行以下命令查看当前 PowerShell 版本,以选择合适方案:

$PSVersionTable.PSVersion

六、总结

旧版 PowerShell 中文字符乱码的核心问题是编码处理机制不完善。通过以下措施可有效解决:

1. 设置控制台编码为 UTF-8[Console]::OutputEncoding = [System.Text.Encoding]::UTF8);

2. 显式声明请求/响应编码Content-Type: application/json; charset=utf-8);

3. 优先使用curl.exe(兼容性最好,避免 PowerShell 隐式编码转换);

4. 手动处理字节数组解码(确保二进制响应正确转换为中文字符)。

通过以上方案,即使在最旧的 PowerShell 版本中,也能确保中文字符正确显示与解析。

 

posted on 2025-07-05 16:46  GoGrid  阅读(176)  评论(0)    收藏  举报

导航