如何在PowerShell中捕获curl.exe返回的HTTP响应码?
问题:如何从带请求体的curl GET请求中提取HTTP响应码?
由于Invoke-WebRequest和.NET原生不支持发起带请求体的GET请求,我使用外部curl.exe工具实现,但目前curl的调试信息仅输出到控制台,$output变量仅包含响应内容,无法提取出HTTP响应码,该如何解决?
原脚本
$header = "Bearer ABCDE" $ContentType = "application/json" $url = "http://test/api" $bodyJson='{""SSELECT1"": ""0"", ""SSELECT2"": ""TEST1""}' $pattern = "(?<=HTTP/1.1 )\d+" $output = & "C:\curl\bin\curl.exe" -X GET -H "Authorization: $header" -H "Content-Type: $ContentType" -d $bodyJson -v $url Write-Host "Response: " $output $httpCode = [regex]::Match($output, $pattern).Groups[1].Value Write-Host "HTTP CODE: " $httpCode
控制台输出
curl.exe : % Total % Received % Xferd Average Speed Time Time Time Current In Zeile:9 Zeichen:15 + ... usgabe = $(&"C:\curl\bin\curl.exe" -X GET -H "Authorization: $header ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: ( % Total % ... Time Current:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Host XY was resolved. * IPv6: (none) * IPv4: 123 * Trying 123... * Connected to celle (123) port xy > GET test/api HTTP/1.1 > Host: 123 > User-Agent: curl/8.6.0 > Accept: */* > Authorization: Bearer ABCDE > Content-Type: application/json > Content-Length: 57 > } [57 bytes data] < HTTP/1.1 200 OK < Connection: keep-alive < Content-Type: application/json < Content-Length: 278 < Date: Thu, 14 Mar 2024 12:15:58 GMT < { [278 bytes data] 100 335 100 278 100 57 2989 613 --:--:-- --:--:-- --:--:-- 3764 * Connection #0 to host XY left intact
最终输出
Response: {"records":[{"value":{"TEST":"1","TEST2":"2"}}]}
解决方法
方案1:用curl的-w参数直接输出响应码(最简洁)
利用curl的-w参数指定输出格式,单独获取响应码,同时保留响应内容。使用-s静默模式隐藏进度条,-S确保错误时仍显示信息。
$header = "Bearer ABCDE" $ContentType = "application/json" $url = "http://test/api" $bodyJson='{"SSELECT1": "0", "SSELECT2": "TEST1"}' # 获取响应内容 $responseContent = & "C:\curl\bin\curl.exe" -X GET -H "Authorization: $header" -H "Content-Type: $ContentType" -d $bodyJson -s -S $url # 仅获取HTTP响应码,丢弃响应内容 $httpCode = & "C:\curl\bin\curl.exe" -X GET -H "Authorization: $header" -H "Content-Type: $ContentType" -d $bodyJson -s -w "%{http_code}" -o nul $url Write-Host "Response: " $responseContent Write-Host "HTTP CODE: " $httpCode
方案2:捕获curl的标准错误流(保留调试信息的同时提取响应码)
curl的-v调试信息输出到标准错误流(stderr),PowerShell中可以通过2>&1将stderr合并到stdout,这样就能在变量中获取所有输出,再用正则匹配响应码。
$header = "Bearer ABCDE" $ContentType = "application/json" $url = "http://test/api" $bodyJson='{"SSELECT1": "0", "SSELECT2": "TEST1"}' $pattern = "(?<=HTTP/1.1 )\d+" # 合并stdout和stderr到一个变量 $allOutput = & "C:\curl\bin\curl.exe" -X GET -H "Authorization: $header" -H "Content-Type: $ContentType" -d $bodyJson -v $url 2>&1 # 过滤出响应内容(排除PowerShell错误提示和调试信息) $responseContent = $allOutput | Where-Object { $_ -is [string] -and $_ -notmatch '^curl.exe :|CategoryInfo|FullyQualifiedErrorId' -and $_ -match '^\{.*\}$' } # 从合并的输出中匹配响应码 $httpCode = [regex]::Match($allOutput -join "`n", $pattern).Value Write-Host "Response: " $responseContent Write-Host "HTTP CODE: " $httpCode
方案3:用--write-out同时输出响应内容和响应码
让curl在响应内容末尾追加响应码,再拆分变量得到两部分内容。
$header = "Bearer ABCDE" $ContentType = "application/json" $url = "http://test/api" $bodyJson='{"SSELECT1": "0", "SSELECT2": "TEST1"}' # 让curl输出响应内容后,换行输出响应码 $combinedOutput = & "C:\curl\bin\curl.exe" -X GET -H "Authorization: $header" -H "Content-Type: $ContentType" -d $bodyJson -s -w "`n%{http_code}" $url # 拆分出响应内容和响应码 $responseContent = $combinedOutput | Select-Object -SkipLast 1 $httpCode = $combinedOutput | Select-Object -Last 1 Write-Host "Response: " $responseContent Write-Host "HTTP CODE: " $httpCode
内容的提问来源于stack exchange,提问作者An Dré
相关产品推荐
相关产品推荐

