System.Net.WebException: 基础连接已经关闭: 无法连接到远程服务器。 ---> System.Net.Sockets.SocketException: 无法加载或初始化请求的服...

本文介绍了一种在多台电脑中仅一台无法访问Webservice的情况下的解决方案。此问题表现为能够Ping通目标服务器,且未开启防火墙,但在尝试访问时出现连接错误。通过重置Winsock,可以在包括XP、win7、win8、win10等多个操作系统上解决这一问题。

工作中遇到的webservice的问题,多台电脑中有一台不能访问,能ping通,没有开防火墙,并且浏览器可以访问服务地址,查看日志文件发现

System.Net.WebException: 基础连接已经关闭: 无法连接到远程服务器。

---> System.Net.Sockets.SocketException: 无法加载或初始化请求的服务提供程序。

这种情况需要重置 Winsock 来解决,该方法适用于 XP、win7、win8、win10 等操作系统,以下以 win7 系统为例:

1)在开始键入 cmd,右键单击“cmd.exe”,选择“以管理员身份运行”,然后按“继续”。

同步助手/微信备份助手遇到服务器访问异常怎么办?

2)在命令提示符处键入 netsh winsock reset,然后按 Enter。

同步助手/微信备份助手遇到服务器访问异常怎么办?

3)重启电脑。

转载于:https://www.cnblogs.com/MR---Zhang/p/8780808.html

PS C:\Users\Administrator> # 加载必要程序集 PS C:\Users\Administrator> Add-Type -AssemblyName System.Net.Http -ErrorAction Stop PS C:\Users\Administrator> PS C:\Users\Administrator> function Invoke-EnhancedCurlRequest { >> [CmdletBinding()] >> param( >> [Parameter(Mandatory=$true)] >> [string]$Uri, >> [ValidateSet('GET','POST','PUT','DELETE','PATCH','HEAD','OPTIONS')] >> [string]$Method = 'GET', >> [hashtable]$Headers = @{}, >> [object]$Body, >> [int]$Timeout = 30, >> [switch]$SkipCertificateCheck, >> [switch]$UseGzipCompression >> ) >> >> $resultTemplate = [PSCustomObject]@{ >> StatusCode = 0 >> StatusMessage = "NotExecuted" >> Headers = [ordered]@{} >> Content = $null >> IsSuccess = $false >> Technology = "None" >> ErrorMessage = $null >> ElapsedMs = 0 >> } >> >> $timer = [System.Diagnostics.Stopwatch]::StartNew() >> $result = $resultTemplate.PSObject.Copy() >> $result.Technology = "HttpClient" >> >> $handler = $null >> $client = $null >> $request = $null >> $response = $null >> $originalCallback = $null >> >> try { >> # 创建 HttpClientHandler >> $handler = New-Object System.Net.Http.HttpClientHandler >> >> # 修复证书验证 - 使用全局设置方案 >> if ($SkipCertificateCheck) { >> $originalCallback = [System.Net.ServicePointManager]::ServerCertificateValidationCallback >> [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { >> param($sender, $cert, $chain, $sslPolicyErrors) >> return $true >> } >> } >> >> if ($UseGzipCompression) { >> $handler.AutomaticDecompression = [System.Net.DecompressionMethods]::GZip >> } >> >> # 创建 HttpClient >> $client = New-Object System.Net.Http.HttpClient($handler) >> >> # 设置超时时间(确保有效) >> if ($Timeout -gt 0) { >> $client.Timeout = [System.TimeSpan]::FromSeconds($Timeout) >> } >> else { >> $client.Timeout = [System.TimeSpan]::FromSeconds(30) >> } >> >> # 创建请求方法对象(兼容方式) >> try { >> $httpMethod = [System.Net.Http.HttpMethod]::new($Method) >> } >> catch { >> $httpMethod = New-Object System.Net.Http.HttpMethod -ArgumentList $Method >> } >> >> # 创建请求消息 >> $request = New-Object System.Net.Http.HttpRequestMessage($httpMethod, $Uri) >> >> # 添加默认 User-Agent >> if (-not $Headers.ContainsKey('User-Agent')) { >> $request.Headers.TryAddWithoutValidation("User-Agent", "PowerShell-HTTPClient/1.0") >> } >> >> # 添加自定义头 >> foreach ($key in $Headers.Keys) { >> if (-not $request.Headers.TryAddWithoutValidation($key, $Headers[$key])) { >> if (-not $request.Content) { >> $request.Content = New-Object System.Net.Http.StringContent("") >> } >> $request.Content.Headers.TryAddWithoutValidation($key, $Headers[$key]) >> } >> } >> >> # 处理请求体 >> if ($Body -and @('POST','PUT','PATCH') -contains $Method) { >> if ($Body -is [byte[]]) { >> $request.Content = New-Object System.Net.Http.ByteArrayContent($Body) >> } >> elseif ($Body -is [hashtable] -or $Body -is [System.Collections.IDictionary]) { >> $jsonBody = $Body | ConvertTo-Json -Depth 5 -Compress >> $request.Content = New-Object System.Net.Http.StringContent( >> $jsonBody, >> [System.Text.Encoding]::UTF8, >> "application/json" >> ) >> } >> elseif ($Body -is [string]) { >> $request.Content = New-Object System.Net.Http.StringContent( >> $Body, >> [System.Text.Encoding]::UTF8 >> ) >> } >> else { >> throw "Unsupported body type: $($Body.GetType().Name)" >> } >> } >> >> # 发送请求 >> $response = $client.SendAsync($request).GetAwaiter().GetResult() >> >> # 解析响应 >> $result.StatusCode = [int]$response.StatusCode >> $result.StatusMessage = $response.ReasonPhrase >> $result.IsSuccess = $response.IsSuccessStatusCode >> >> $result.Headers = [ordered]@{} >> foreach ($header in $response.Headers) { >> $result.Headers[$header.Key] = $header.Value -join ", " >> } >> >> foreach ($header in $response.Content.Headers) { >> $result.Headers[$header.Key] = $header.Value -join ", " >> } >> >> $result.Content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult() >> return $result >> } >> catch [System.Threading.Tasks.TaskCanceledException] { >> $result.ErrorMessage = "Request timed out after $Timeout seconds" >> $result.StatusCode = 408 >> $result.StatusMessage = "Timeout" >> return $result >> } >> catch [System.Net.Http.HttpRequestException] { >> # 处理特定HTTP请求异常 >> $ex = $_.Exception >> $result.ErrorMessage = $ex.ToString() >> >> # 检查内部异常是否为SocketException(DNS解析错误) >> if ($ex.InnerException -is [System.Net.Sockets.SocketException]) { >> $result.StatusCode = 0 >> $result.StatusMessage = "DNSResolutionFailed" >> } >> else { >> $result.StatusCode = 500 >> $result.StatusMessage = "HttpRequestError" >> } >> >> return $result >> } >> catch { >> # 通用错误处理 >> $result.ErrorMessage = $_.Exception.ToString() >> $result.StatusCode = 500 >> $result.StatusMessage = "InternalError" >> return $result >> } >> finally { >> $timer.Stop() >> $result.ElapsedMs = $timer.ElapsedMilliseconds >> >> # 安全清理资源 >> if ($response -is [IDisposable]) { $response.Dispose() } >> if ($request -is [IDisposable]) { $request.Dispose() } >> if ($client -is [IDisposable]) { $client.Dispose() } >> if ($handler -is [IDisposable]) { $handler.Dispose() } >> >> # 恢复全局证书验证设置 >> if ($SkipCertificateCheck -and $null -ne $originalCallback) { >> [System.Net.ServicePointManager]::ServerCertificateValidationCallback = $originalCallback >> } >> } >> } >> PS C:\Users\Administrator> # 创建模块目录 PS C:\Users\Administrator> $moduleDir = "$env:ProgramFiles\WindowsPowerShell\Modules\PSHttpClient" PS C:\Users\Administrator> New-Item -Path $moduleDir -ItemType Directory -Force | Out-Null PS C:\Users\Administrator> PS C:\Users\Administrator> # 保存模块文件 PS C:\Users\Administrator> @' >> # 将上面完整的函数代码复制到这里 >> '@ | Out-File "$moduleDir\PSHttpClient.psm1" -Encoding UTF8 -Force >> PS C:\Users\Administrator> # 创建模块清单 PS C:\Users\Administrator> New-ModuleManifest -Path "$moduleDir\PSHttpClient.psd1" ` >> -RootModule "PSHttpClient.psm1" ` >> -Author "YourName" ` >> -ModuleVersion "1.0" ` >> -Description "Enhanced HTTP Client for PowerShell" >> PS C:\Users\Administrator> # 重新加载模块 PS C:\Users\Administrator> Remove-Module PSHttpClient -ErrorAction SilentlyContinue PS C:\Users\Administrator> Import-Module PSHttpClient -Force -PassThru ModuleType Version Name ExportedCommands ---------- ------- ---- ---------------- Script 1.0 PSHttpClient PS C:\Users\Administrator> # 测试自签名证书网站 PS C:\Users\Administrator> $result = Invoke-EnhancedCurlRequest -Uri "https://self-signed.badssl.com/" -SkipCertificateCheck PS C:\Users\Administrator> PS C:\Users\Administrator> if ($result.IsSuccess) { >> Write-Host "✅ 自签名证书网站访问成功" -ForegroundColor Green >> $result.Headers >> } else { >> Write-Host "❌ 自签名证书网站访问失败: $($result.ErrorMessage)" -ForegroundColor Red >> } >> ❌ 自签名证书网站访问失败: System.Net.Http.HttpRequestException: 发送请求时出错。 ---> System.Net.WebException: 基础连接已经关闭: 发送时发生错误。 ---> System.Management.Automation.PSInvalidOperationException: 此线程中没有可用于运行脚本的运行空间。你可以在 System.Management.Automation.Runspaces.Runspace 类型的 DefaultRunspace 属性中提供一个运行空间。你尝试调用的脚本块为: ...ue 在 System.Net.TlsStream.EndWrite(IAsyncResult asyncResult) 在 System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar) --- 内部异常堆栈跟踪的结尾 ---System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) 在 System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar) --- 内部异常堆栈跟踪的结尾 ---System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 CallSite.Target(Closure , CallSite , Object ) PS C:\Users\Administrator> # 测试无效域名 PS C:\Users\Administrator> $result = Invoke-EnhancedCurlRequest -Uri "https://invalid.domain.abc/" PS C:\Users\Administrator> PS C:\Users\Administrator> if ($result.StatusCode -eq 0) { >> Write-Host "✅ DNS错误处理成功" -ForegroundColor Green >> } else { >> Write-Host "❌ DNS错误处理失败: $($result.StatusCode)" -ForegroundColor Red >> } >> ❌ DNS错误处理失败: 500 PS C:\Users\Administrator> # 测试正常网站 PS C:\Users\Administrator> $result = Invoke-EnhancedCurlRequest -Uri "https://httpbin.org/get" PS C:\Users\Administrator> PS C:\Users\Administrator> if ($result.IsSuccess) { >> Write-Host "✅ 正常网站访问成功" -ForegroundColor Green >> $result.Content | ConvertFrom-Json >> } else { >> Write-Host "❌ 正常网站访问失败: $($result.ErrorMessage)" -ForegroundColor Red >> } >> ❌ 正常网站访问失败: System.Net.Http.HttpRequestException: 发送请求时出错。 ---> System.Net.WebException: 基础连接已经关闭: 发送时发生错误。 ---> System.Management.Automation.PSInvalidOperationException: 此线程中没有可用于运行脚本的运行空间。你可以在 System.Management.Automation.Runspaces.Runspace 类型的 DefaultRunspace 属性中提供一个运行空间。你尝试调用的脚本块为: ...ue 在 System.Net.TlsStream.EndWrite(IAsyncResult asyncResult) 在 System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar) --- 内部异常堆栈跟踪的结尾 ---System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) 在 System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar) --- 内部异常堆栈跟踪的结尾 ---System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 CallSite.Target(Closure , CallSite , Object ) PS C:\Users\Administrator> # 测试POST请求 PS C:\Users\Administrator> $postData = @{ >> name = "John Doe" >> email = "john@example.com" >> } >> $result = Invoke-EnhancedCurlRequest -Uri "https://httpbin.org/post" -Method POST -Body $postData >> PS C:\Users\Administrator> if ($result.IsSuccess) { >> Write-Host "✅ POST请求成功" -ForegroundColor Green >> ($result.Content | ConvertFrom-Json).json >> } else { >> Write-Host "❌ POST请求失败: $($result.StatusCode)" -ForegroundColor Red >> } >> ❌ POST请求失败: 500 PS C:\Users\Administrator>
08-17
PS C:\Users\Administrator> # 1. 修复模块路径问题 PS C:\Users\Administrator> $moduleBase = "E:\PowerShellModules\PSHttpClient" PS C:\Users\Administrator> $modulePath = "$moduleBase\1.2.1" PS C:\Users\Administrator> $moduleFile = "$modulePath\PSHttpClient.psm1" PS C:\Users\Administrator> $manifestFile = "$modulePath\PSHttpClient.psd1" PS C:\Users\Administrator> PS C:\Users\Administrator> # 确保目录存在 PS C:\Users\Administrator> New-Item -Path $modulePath -ItemType Directory -Force | Out-Null PS C:\Users\Administrator> PS C:\Users\Administrator> # 2. 创建完全修复的模块文件 PS C:\Users\Administrator> @' >> function Invoke-EnhancedCurlRequest { >> [CmdletBinding()] >> param( >> [Parameter(Mandatory=$true)] >> [string]$Uri, >> [ValidateSet('GET','POST','PUT','DELETE','PATCH','HEAD','OPTIONS')] >> [string]$Method = 'GET', >> [hashtable]$Headers = @{}, >> [object]$Body, >> [int]$Timeout = 30, >> [switch]$SkipCertificateCheck, >> [switch]$UseGzipCompression, >> [switch]$EnableHttp2 >> ) >> >> # 错误类型定义 >> $connectionErrors = @( >> [System.Net.Http.HttpRequestException], >> [System.Net.WebException], >> [System.Net.Sockets.SocketException], >> [System.Threading.Tasks.TaskCanceledException] >> ) >> >> $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() >> >> try { >> # 关键修复1:显式加载必需程序集 >> Add-Type -AssemblyName System.Net.Http -ErrorAction Stop >> Add-Type -AssemblyName System.Collections -ErrorAction Stop >> Add-Type -AssemblyName System.Runtime -ErrorAction Stop >> >> # 关键修复2:扩展TLS兼容性 >> $tlsSettings = [System.Net.SecurityProtocolType]::Tls12 >> $availableProtocols = [enum]::GetValues([System.Net.SecurityProtocolType]) >> >> if ($availableProtocols -contains [System.Net.SecurityProtocolType]::Tls13) { >> $tlsSettings = $tlsSettings -bor [System.Net.SecurityProtocolType]::Tls13 >> } >> if ($availableProtocols -contains [System.Net.SecurityProtocolType]::Tls11) { >> $tlsSettings = $tlsSettings -bor [System.Net.SecurityProtocolType]::Tls11 >> } >> if ($availableProtocols -contains [System.Net.SecurityProtocolType]::Tls) { >> $tlsSettings = $tlsSettings -bor [System.Net.SecurityProtocolType]::Tls >> } >> if ($availableProtocols -contains [System.Net.SecurityProtocolType]::Ssl3) { >> $tlsSettings = $tlsSettings -bor [System.Net.SecurityProtocolType]::Ssl3 >> } >> >> [System.Net.ServicePointManager]::SecurityProtocol = $tlsSettings >> >> # 创建HttpClientHandler >> $handler = New-Object System.Net.Http.HttpClientHandler >> >> # 关键修复3:增强证书验证 >> if ($SkipCertificateCheck) { >> $handler.ServerCertificateCustomValidationCallback = { >> param($sender, $cert, $chain, $errors) >> return $true >> } >> } >> >> if ($UseGzipCompression) { >> $handler.AutomaticDecompression = [System.Net.DecompressionMethods]::GZip >> } >> >> # 创建HttpClient >> $client = New-Object System.Net.Http.HttpClient($handler) >> $client.Timeout = [System.TimeSpan]::FromSeconds($Timeout) >> if ($EnableHttp2) { >> $client.DefaultRequestVersion = [System.Net.HttpVersion]::Version20 >> } >> >> # 创建请求消息 >> $request = New-Object System.Net.Http.HttpRequestMessage([System.Net.Http.HttpMethod]::$Method, $Uri) >> >> # 设置User-Agent >> if (-not $Headers.ContainsKey("User-Agent")) { >> $request.Headers.Add("User-Agent", "PowerShell-HTTP-Client/1.0") >> } >> >> # 添加自定义请求头 >> foreach ($key in $Headers.Keys) { >> $request.Headers.TryAddWithoutValidation($key, $Headers[$key]) | Out-Null >> } >> >> # 关键修复4:表单处理(保持之前成功的实现) >> if ($null -ne $Body) { >> $content = $null >> >> if ($Body -is [System.Collections.IDictionary]) { >> $formContent = [System.Net.Http.MultipartFormDataContent]::new() >> >> foreach ($key in $Body.Keys) { >> $value = $Body[$key] >> >> if ($value -is [System.IO.FileInfo]) { >> $fileStream = [System.IO.File]::OpenRead($value.FullName) >> $fileContent = New-Object System.Net.Http.StreamContent($fileStream) >> $formContent.Add($fileContent, $key, $value.Name) >> } >> elseif ($value -is [array]) { >> foreach ($item in $value) { >> $stringContent = New-Object System.Net.Http.StringContent($item.ToString()) >> $formContent.Add($stringContent, $key) >> } >> } >> else { >> $stringContent = New-Object System.Net.Http.StringContent($value.ToString()) >> $formContent.Add($stringContent, $key) >> } >> } >> >> $content = $formContent >> } >> elseif ($Body -is [string] -and $Body.StartsWith("{") -and $Body.EndsWith("}")) { >> $content = New-Object System.Net.Http.StringContent($Body, [System.Text.Encoding]::UTF8) >> $content.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse("application/json") >> } >> elseif ($Body -is [string]) { >> $content = New-Object System.Net.Http.StringContent($Body, [System.Text.Encoding]::UTF8) >> $content.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse("text/plain") >> } >> elseif ($Body -is [byte[]]) { >> $content = New-Object System.Net.Http.ByteArrayContent($Body) >> } >> else { >> $content = New-Object System.Net.Http.StringContent($Body.ToString(), [System.Text.Encoding]::UTF8) >> } >> >> $request.Content = $content >> } >> >> # 关键修复5:重构异步调用(解决ScriptHalted问题) >> try { >> # 创建异步任务 >> $task = $client.SendAsync($request) >> >> # 使用更可靠的异步等待方式 >> $asyncResult = $task.GetAwaiter().GetResult() >> >> # 检查任务状态 >> if ($task.IsFaulted) { >> throw $task.Exception.InnerException >> } >> >> if ($task.IsCanceled) { >> throw [System.Threading.Tasks.TaskCanceledException]::new("Request was canceled") >> } >> >> $response = $asyncResult >> >> # 检查响应状态 >> if (-not $response.IsSuccessStatusCode) { >> $errorResponse = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult() >> throw [System.Net.Http.HttpRequestException]::new( >> "HTTP error: $([int]$response.StatusCode) $($response.ReasonPhrase). Response: $errorResponse" >> ) >> } >> } >> catch [System.AggregateException] { >> throw $_.InnerException >> } >> >> # 关键修复6:空值检查 >> if ($null -eq $response) { >> throw [System.Net.WebException]::new("Response is null") >> } >> >> # 处理响应 >> $responseContent = $null >> if ($null -ne $response.Content) { >> $responseContent = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult() >> } >> >> # 返回结果对象 >> [PSCustomObject]@{ >> StatusCode = [int]$response.StatusCode >> StatusMessage = $response.ReasonPhrase >> Content = $responseContent >> Headers = $response.Headers >> Technology = "HttpClient (.NET)" >> Protocol = $response.Version.ToString() >> ElapsedMs = $stopwatch.ElapsedMilliseconds >> } >> } >> catch { >> $statusCode = 500 >> $errorMsg = $_.Exception.Message >> $exceptionType = $_.Exception.GetType().Name >> >> # 识别特定错误 >> if ($_.Exception -is [System.Net.Http.HttpRequestException]) { >> $statusCode = 503 >> $errorMsg = "HTTP Request Error: $errorMsg" >> } >> elseif ($_.Exception -is [System.Net.WebException]) { >> $statusCode = 503 >> $errorMsg = "Web Exception: $errorMsg" >> } >> elseif ($_.Exception -is [System.Net.Sockets.SocketException]) { >> $statusCode = 503 >> $errorMsg = "Network Error: $errorMsg" >> } >> elseif ($_.Exception -is [System.Threading.Tasks.TaskCanceledException]) { >> $statusCode = 504 >> $errorMsg = "Request Timeout: $errorMsg" >> } >> elseif ($_.Exception -is [System.Security.Authentication.AuthenticationException]) { >> $statusCode = 495 >> $errorMsg = "SSL/TLS Handshake Failed: $errorMsg" >> } >> >> # 返回错误对象 >> [PSCustomObject]@{ >> StatusCode = $statusCode >> StatusMessage = "Request Failed" >> Error = $errorMsg >> ExceptionType = $exceptionType >> StackTrace = $_.ScriptStackTrace >> } >> } >> finally { >> $stopwatch.Stop() >> if ($client) { $client.Dispose() } >> if ($handler) { $handler.Dispose() } >> } >> } >> >> Export-ModuleMember -Function Invoke-EnhancedCurlRequest >> '@ | Out-File $moduleFile -Encoding UTF8 -Force >> PS C:\Users\Administrator> # 3. 创建模块清单 PS C:\Users\Administrator> @" >> @{ >> RootModule = 'PSHttpClient.psm1' >> ModuleVersion = '1.2.1' >> GUID = '$([guid]::NewGuid().ToString())' >> Author = 'PowerShell User' >> CompanyName = 'N/A' >> Copyright = '(c) $(Get-Date -Format yyyy). All rights reserved.' >> Description = 'Enhanced HTTP client for PowerShell' >> PowerShellVersion = '5.1' >> FunctionsToExport = @('Invoke-EnhancedCurlRequest') >> RequiredAssemblies = @('System.Net.Http') >> } >> "@ | Out-File $manifestFile -Encoding UTF8 -Force >> PS C:\Users\Administrator> # 4. 配置模块路径 PS C:\Users\Administrator> $env:PSModulePath = "$moduleBase;$env:PSModulePath" PS C:\Users\Administrator> [Environment]::SetEnvironmentVariable('PSModulePath', $env:PSModulePath, 'User') PS C:\Users\Administrator> PS C:\Users\Administrator> # 5. 创建全局http函数 PS C:\Users\Administrator> function global:http { >> param( >> [Parameter(Mandatory=$true)] >> [string]$Uri, >> [ValidateSet('GET','POST','PUT','DELETE','PATCH','HEAD','OPTIONS')] >> [string]$Method = 'GET', >> [object]$Body, >> [hashtable]$Headers, >> [int]$Timeout, >> [switch]$SkipCertificateCheck, >> [switch]$UseGzipCompression, >> [switch]$EnableHttp2 >> ) >> >> $params = @{ >> Uri = $Uri >> Method = $Method >> } >> >> if ($PSBoundParameters.ContainsKey('Body')) { $params['Body'] = $Body } >> if ($PSBoundParameters.ContainsKey('Headers')) { $params['Headers'] = $Headers } >> if ($PSBoundParameters.ContainsKey('Timeout')) { $params['Timeout'] = $Timeout } >> if ($SkipCertificateCheck) { $params['SkipCertificateCheck'] = $true } >> if ($UseGzipCompression) { $params['UseGzipCompression'] = $true } >> if ($EnableHttp2) { $params['EnableHttp2'] = $true } >> >> Invoke-EnhancedCurlRequest @params >> } >> PS C:\Users\Administrator> # 6. 导入模块(使用绝对路径) PS C:\Users\Administrator> Remove-Module PSHttpClient -ErrorAction SilentlyContinue PS C:\Users\Administrator> Import-Module $manifestFile -Force -ErrorAction Stop PS C:\Users\Administrator> PS C:\Users\Administrator> # 7. 运行最终测试 PS C:\Users\Administrator> Write-Host "`n=== 最终测试 ===" -ForegroundColor Cyan === 最终测试 === PS C:\Users\Administrator> PS C:\Users\Administrator> # 测试1:GET请求验证User-Agent PS C:\Users\Administrator> Write-Host "`n[测试1] GET请求 - 验证User-Agent" -ForegroundColor Yellow [测试1] GET请求 - 验证User-Agent PS C:\Users\Administrator> $getResult = http -Method GET -Uri "https://httpbin.org/user-agent" PS C:\Users\Administrator> $getResult | Format-List StatusCode, StatusMessage, Content, Technology, Protocol, ElapsedMs StatusCode : 200 StatusMessage : OK Content : { "user-agent": "PowerShell-HTTP-Client/1.0" } Technology : HttpClient (.NET) Protocol : 1.1 ElapsedMs : 1142 PS C:\Users\Administrator> PS C:\Users\Administrator> # 测试2:POST表单数据 PS C:\Users\Administrator> Write-Host "`n[测试2] POST表单数据" -ForegroundColor Yellow [测试2] POST表单数据 PS C:\Users\Administrator> $formData = @{ >> username = "admin" >> password = "P@ssw0rd!" >> role = "administrator" >> } >> $postResult = http -Method POST -Uri "https://httpbin.org/post" -Body $formData >> $postResult | Format-List StatusCode, StatusMessage, Content, Technology, Protocol, ElapsedMs >> StatusCode : 200 StatusMessage : OK Content : { "args": {}, "data": "", "files": {}, "form": { "password": "P@ssw0rd!", "role": "administrator", "username": "admin" }, "headers": { "Content-Length": "461", "Content-Type": "multipart/form-data; boundary=\"b57ffbcf-bd54-4bcd-8eae-749acf779889\"", "Host": "httpbin.org", "User-Agent": "PowerShell-HTTP-Client/1.0", "X-Amzn-Trace-Id": "Root=1-68a0a9cf-5d1cc77c0569b5e70210eb9c" }, "json": null, "origin": "112.40.123.16", "url": "https://httpbin.org/post" } Technology : HttpClient (.NET) Protocol : 1.1 ElapsedMs : 1379 PS C:\Users\Administrator> # 测试3:自签名证书验证 PS C:\Users\Administrator> Write-Host "`n[测试3] 自签名证书验证" -ForegroundColor Yellow [测试3] 自签名证书验证 PS C:\Users\Administrator> $sslResult = http -Method GET -Uri "https://self-signed.badssl.com" -SkipCertificateCheck PS C:\Users\Administrator> $sslResult | Format-List StatusCode, StatusMessage, Content, Technology, Protocol, ElapsedMs StatusCode : 500 StatusMessage : Request Failed PS C:\Users\Administrator> PS C:\Users\Administrator> # 验证结果 PS C:\Users\Administrator> if ($postResult.StatusCode -eq 200 -and $postResult.Content) { >> $json = $postResult.Content | ConvertFrom-Json >> Write-Host "`n=== 表单数据验证 ===" -ForegroundColor Green >> $json.form >> } else { >> Write-Host "`nPOST请求失败!详情:" -ForegroundColor Red >> $postResult | Format-List * >> } >> === 表单数据验证 === password role username -------- ---- -------- P@ssw0rd! administrator admin PS C:\Users\Administrator> if ($sslResult.StatusCode -eq 200) { >> Write-Host "`n自签名证书验证成功!" -ForegroundColor Green >> } else { >> Write-Host "`n自签名证书验证失败!详情:" -ForegroundColor Red >> $sslResult | Format-List * >> } >> 自签名证书验证失败!详情: StatusCode : 500 StatusMessage : Request Failed Error : 使用“0”个参数调用“GetResult”时发生异常:“发送请求时出错。” ExceptionType : MethodInvocationException StackTrace : 在 Invoke-EnhancedCurlRequest、E:\PowerShellModules\PSHttpClient\1.2.1\PSHttpClient.psm1 中: 第 118 行 在 global:http、<无文件> 中: 第 24 行 在 <ScriptBlock>、<无文件> 中: 第 1 行 PS C:\Users\Administrator> Write-Host "`n所有修复已完成!系统准备就绪`n" -ForegroundColor Green 所有修复已完成!系统准备就绪
最新发布
08-17
PS C:\Users\Administrator> # 1. 修复模块路径问题 PS C:\Users\Administrator> $moduleBase = "E:\PowerShellModules\PSHttpClient" PS C:\Users\Administrator> $modulePath = "$moduleBase\1.2.1" PS C:\Users\Administrator> $moduleFile = "$modulePath\PSHttpClient.psm1" PS C:\Users\Administrator> $manifestFile = "$modulePath\PSHttpClient.psd1" PS C:\Users\Administrator> PS C:\Users\Administrator> # 确保目录存在 PS C:\Users\Administrator> New-Item -Path $modulePath -ItemType Directory -Force | Out-Null PS C:\Users\Administrator> PS C:\Users\Administrator> # 2. 创建完全修复的模块文件 PS C:\Users\Administrator> @' >> function Invoke-EnhancedCurlRequest { >> [CmdletBinding()] >> param( >> [Parameter(Mandatory=$true)] >> [string]$Uri, >> [ValidateSet('GET','POST','PUT','DELETE','PATCH','HEAD','OPTIONS')] >> [string]$Method = 'GET', >> [hashtable]$Headers = @{}, >> [object]$Body, >> [int]$Timeout = 30, >> [switch]$SkipCertificateCheck, >> [switch]$UseGzipCompression, >> [switch]$EnableHttp2 >> ) >> >> # 错误类型定义 >> $connectionErrors = @( >> [System.Net.Http.HttpRequestException], >> [System.Net.WebException], >> [System.Net.Sockets.SocketException] >> ) >> >> $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() >> >> try { >> # 关键修复1:显式加载必需程序集 >> Add-Type -AssemblyName System.Net.Http -ErrorAction Stop >> Add-Type -AssemblyName System.Collections -ErrorAction Stop >> Add-Type -AssemblyName System.Runtime -ErrorAction Stop >> >> # 关键修复2:使用兼容性更好的TLS设置 >> $tls12 = [System.Net.SecurityProtocolType]::Tls12 >> $tls13 = [enum]::GetValues([System.Net.SecurityProtocolType]) | Where-Object { $_ -match 'Tls13' } >> if ($tls13) { >> [System.Net.ServicePointManager]::SecurityProtocol = $tls12 -bor $tls13 >> } else { >> [System.Net.ServicePointManager]::SecurityProtocol = $tls12 >> } >> >> # 创建HttpClientHandler >> $handler = New-Object System.Net.Http.HttpClientHandler >> >> # 关键修复3:修复证书验证问题 >> if ($SkipCertificateCheck) { >> $handler.ServerCertificateCustomValidationCallback = { >> param($sender, $cert, $chain, $errors) >> return $true >> } >> } >> >> if ($UseGzipCompression) { >> $handler.AutomaticDecompression = [System.Net.DecompressionMethods]::GZip >> } >> >> # 创建HttpClient >> $client = New-Object System.Net.Http.HttpClient($handler) >> $client.Timeout = [System.TimeSpan]::FromSeconds($Timeout) >> if ($EnableHttp2) { >> $client.DefaultRequestVersion = [System.Net.HttpVersion]::Version20 >> } >> >> # 创建请求消息 >> $request = New-Object System.Net.Http.HttpRequestMessage([System.Net.Http.HttpMethod]::$Method, $Uri) >> >> # 设置User-Agent >> if (-not $Headers.ContainsKey("User-Agent")) { >> $request.Headers.Add("User-Agent", "PowerShell-HTTP-Client/1.0") >> } >> >> # 添加自定义请求头 >> foreach ($key in $Headers.Keys) { >> $request.Headers.TryAddWithoutValidation($key, $Headers[$key]) | Out-Null >> } >> >> # 关键修复4:完全重构表单处理 >> if ($null -ne $Body) { >> $content = $null >> >> # 处理表单数据 - 完全重构 >> if ($Body -is [System.Collections.IDictionary]) { >> # 使用兼容方式创建表单内容 >> $formContent = [System.Net.Http.MultipartFormDataContent]::new() >> >> foreach ($key in $Body.Keys) { >> $value = $Body[$key] >> >> # 处理不同类型的值 >> if ($value -is [System.IO.FileInfo]) { >> # 文件上传处理 >> $fileStream = [System.IO.File]::OpenRead($value.FullName) >> $fileContent = New-Object System.Net.Http.StreamContent($fileStream) >> $formContent.Add($fileContent, $key, $value.Name) >> } >> elseif ($value -is [array]) { >> # 数组值处理 >> foreach ($item in $value) { >> $stringContent = New-Object System.Net.Http.StringContent($item.ToString()) >> $formContent.Add($stringContent, $key) >> } >> } >> else { >> # 普通值处理 >> $stringContent = New-Object System.Net.Http.StringContent($value.ToString()) >> $formContent.Add($stringContent, $key) >> } >> } >> >> $content = $formContent >> } >> # 处理JSON数据 >> elseif ($Body -is [string] -and $Body.StartsWith("{") -and $Body.EndsWith("}")) { >> $content = New-Object System.Net.Http.StringContent($Body, [System.Text.Encoding]::UTF8) >> $content.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse("application/json") >> } >> # 处理文本数据 >> elseif ($Body -is [string]) { >> $content = New-Object System.Net.Http.StringContent($Body, [System.Text.Encoding]::UTF8) >> $content.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse("text/plain") >> } >> # 处理二进制数据 >> elseif ($Body -is [byte[]]) { >> $content = New-Object System.Net.Http.ByteArrayContent($Body) >> } >> # 其他类型 >> else { >> $content = New-Object System.Net.Http.StringContent($Body.ToString(), [System.Text.Encoding]::UTF8) >> } >> >> $request.Content = $content >> } >> >> # 关键修复5:完全重构异步调用 >> try { >> # 创建异步任务 >> $task = $client.SendAsync($request) >> >> # 等待任务完成(带超时处理) >> if (-not $task.Wait($Timeout * 1000)) { >> throw [System.TimeoutException]::new("Request timed out") >> } >> >> # 获取响应 >> $response = $task.Result >> >> # 检查响应状态 >> if (-not $response.IsSuccessStatusCode) { >> $response.EnsureSuccessStatusCode() | Out-Null >> } >> } >> catch [System.AggregateException] { >> # 处理异步操作中的异常 >> throw $_.InnerException >> } >> catch { >> throw $_ >> } >> >> # 关键修复6:空值检查 >> if ($null -eq $response) { >> throw [System.Net.WebException]::new("Response is null") >> } >> >> # 处理响应 >> $responseContent = $null >> if ($null -ne $response.Content) { >> $responseContent = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult() >> } >> >> # 返回结果对象 >> [PSCustomObject]@{ >> StatusCode = [int]$response.StatusCode >> StatusMessage = $response.ReasonPhrase >> Content = $responseContent >> Headers = $response.Headers >> Technology = "HttpClient (.NET)" >> Protocol = $response.Version.ToString() >> ElapsedMs = $stopwatch.ElapsedMilliseconds >> } >> } >> catch { >> $statusCode = 500 >> $errorMsg = $_.Exception.Message >> $exceptionType = $_.Exception.GetType().Name >> >> # 识别网络错误 >> foreach ($errType in $connectionErrors) { >> if ($_.Exception -is $errType -or $_.Exception.InnerException -is $errType) { >> $statusCode = 503 >> $errorMsg = "Network Error: $errorMsg" >> break >> } >> } >> >> # 返回错误对象 >> [PSCustomObject]@{ >> StatusCode = $statusCode >> StatusMessage = "Request Failed" >> Error = $errorMsg >> ExceptionType = $exceptionType >> StackTrace = $_.ScriptStackTrace >> } >> } >> finally { >> $stopwatch.Stop() >> if ($client) { $client.Dispose() } >> if ($handler) { $handler.Dispose() } >> } >> } >> >> Export-ModuleMember -Function Invoke-EnhancedCurlRequest >> '@ | Out-File $moduleFile -Encoding UTF8 -Force >> PS C:\Users\Administrator> # 3. 创建模块清单 PS C:\Users\Administrator> @" >> @{ >> RootModule = 'PSHttpClient.psm1' >> ModuleVersion = '1.2.1' >> GUID = '$([guid]::NewGuid().ToString())' >> Author = 'PowerShell User' >> CompanyName = 'N/A' >> Copyright = '(c) $(Get-Date -Format yyyy). All rights reserved.' >> Description = 'Enhanced HTTP client for PowerShell' >> PowerShellVersion = '5.1' >> FunctionsToExport = @('Invoke-EnhancedCurlRequest') >> RequiredAssemblies = @('System.Net.Http') >> } >> "@ | Out-File $manifestFile -Encoding UTF8 -Force >> PS C:\Users\Administrator> # 4. 配置模块路径 PS C:\Users\Administrator> $env:PSModulePath = "$moduleBase;$env:PSModulePath" PS C:\Users\Administrator> [Environment]::SetEnvironmentVariable('PSModulePath', $env:PSModulePath, 'User') PS C:\Users\Administrator> PS C:\Users\Administrator> # 5. 创建全局http函数 PS C:\Users\Administrator> function global:http { >> param( >> [Parameter(Mandatory=$true)] >> [string]$Uri, >> [ValidateSet('GET','POST','PUT','DELETE','PATCH','HEAD','OPTIONS')] >> [string]$Method = 'GET', >> [object]$Body, >> [hashtable]$Headers, >> [int]$Timeout, >> [switch]$SkipCertificateCheck, >> [switch]$UseGzipCompression, >> [switch]$EnableHttp2 >> ) >> >> $params = @{ >> Uri = $Uri >> Method = $Method >> } >> >> if ($PSBoundParameters.ContainsKey('Body')) { $params['Body'] = $Body } >> if ($PSBoundParameters.ContainsKey('Headers')) { $params['Headers'] = $Headers } >> if ($PSBoundParameters.ContainsKey('Timeout')) { $params['Timeout'] = $Timeout } >> if ($SkipCertificateCheck) { $params['SkipCertificateCheck'] = $true } >> if ($UseGzipCompression) { $params['UseGzipCompression'] = $true } >> if ($EnableHttp2) { $params['EnableHttp2'] = $true } >> >> Invoke-EnhancedCurlRequest @params >> } >> PS C:\Users\Administrator> # 6. 导入模块(使用绝对路径) PS C:\Users\Administrator> Remove-Module PSHttpClient -ErrorAction SilentlyContinue PS C:\Users\Administrator> Import-Module $manifestFile -Force -ErrorAction Stop PS C:\Users\Administrator> PS C:\Users\Administrator> # 7. 运行最终测试 PS C:\Users\Administrator> Write-Host "`n=== 最终测试 ===" -ForegroundColor Cyan === 最终测试 === PS C:\Users\Administrator> PS C:\Users\Administrator> # 测试1:GET请求验证User-Agent PS C:\Users\Administrator> Write-Host "`n[测试1] GET请求 - 验证User-Agent" -ForegroundColor Yellow [测试1] GET请求 - 验证User-Agent PS C:\Users\Administrator> $getResult = http -Method GET -Uri "https://httpbin.org/user-agent" PS C:\Users\Administrator> $getResult | Format-List StatusCode, StatusMessage, Content, Technology, Protocol, ElapsedMs StatusCode : 200 StatusMessage : OK Content : { "user-agent": "PowerShell-HTTP-Client/1.0" } Technology : HttpClient (.NET) Protocol : 1.1 ElapsedMs : 1318 PS C:\Users\Administrator> PS C:\Users\Administrator> # 测试2:POST表单数据 PS C:\Users\Administrator> Write-Host "`n[测试2] POST表单数据" -ForegroundColor Yellow [测试2] POST表单数据 PS C:\Users\Administrator> $formData = @{ >> username = "admin" >> password = "P@ssw0rd!" >> role = "administrator" >> } >> $postResult = http -Method POST -Uri "https://httpbin.org/post" -Body $formData >> $postResult | Format-List StatusCode, StatusMessage, Content, Technology, Protocol, ElapsedMs >> StatusCode : 200 StatusMessage : OK Content : { "args": {}, "data": "", "files": {}, "form": { "password": "P@ssw0rd!", "role": "administrator", "username": "admin" }, "headers": { "Content-Length": "461", "Content-Type": "multipart/form-data; boundary=\"04c07b56-9f48-4f2d-a6bb-85b14e05bd24\"", "Host": "httpbin.org", "User-Agent": "PowerShell-HTTP-Client/1.0", "X-Amzn-Trace-Id": "Root=1-68a0a70e-076d1a97493cb41f79e2575a" }, "json": null, "origin": "112.40.123.16", "url": "https://httpbin.org/post" } Technology : HttpClient (.NET) Protocol : 1.1 ElapsedMs : 1400 PS C:\Users\Administrator> # 测试3:自签名证书验证 PS C:\Users\Administrator> Write-Host "`n[测试3] 自签名证书验证" -ForegroundColor Yellow [测试3] 自签名证书验证 PS C:\Users\Administrator> $sslResult = http -Method GET -Uri "https://self-signed.badssl.com" -SkipCertificateCheck PS C:\Users\Administrator> $sslResult | Format-List StatusCode, StatusMessage, Content, Technology, Protocol, ElapsedMs StatusCode : 500 StatusMessage : Request Failed PS C:\Users\Administrator> PS C:\Users\Administrator> # 验证结果 PS C:\Users\Administrator> if ($postResult.StatusCode -eq 200 -and $postResult.Content) { >> $json = $postResult.Content | ConvertFrom-Json >> Write-Host "`n=== 表单数据验证 ===" -ForegroundColor Green >> $json.form >> } else { >> Write-Host "`nPOST请求失败!详情:" -ForegroundColor Red >> $postResult | Format-List * >> } >> === 表单数据验证 === password role username -------- ---- -------- P@ssw0rd! administrator admin PS C:\Users\Administrator> if ($sslResult.StatusCode -eq 200) { >> Write-Host "`n自签名证书验证成功!" -ForegroundColor Green >> } else { >> Write-Host "`n自签名证书验证失败!详情:" -ForegroundColor Red >> $sslResult | Format-List * >> } >> 自签名证书验证失败!详情: StatusCode : 500 StatusMessage : Request Failed Error : ScriptHalted ExceptionType : RuntimeException StackTrace : 在 Invoke-EnhancedCurlRequest、E:\PowerShellModules\PSHttpClient\1.2.1\PSHttpClient.psm1 中: 第 131 行 在 global:http、<无文件> 中: 第 24 行 在 <ScriptBlock>、<无文件> 中: 第 1 行 PS C:\Users\Administrator> Write-Host "`n所有修复已完成!系统准备就绪`n" -ForegroundColor Green 所有修复已完成!系统准备就绪
08-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值