当我运行以下语句时
Invoke-RestMethod "https://api.mysite.com/the/endpoint" `
-Body (ConvertTo-Json $data) `
-ContentType "application/json" `
-Headers $DefaultHttpHeaders `
-Method Post
Run Code Online (Sandbox Code Playgroud)
端点返回400 Bad Request,这会导致PowerShell显示以下不太有用的消息:
Invoke-WebRequest : The remote server returned an error: (400) Bad Request.
At line:1 char:1
+ Invoke-WebRequest "https://api.mysite.com/the/endpoint" -Body ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
我如何获得响应的正文,这可能告诉我发送的请求有什么问题?
小智 28
有使用PowerShell一个已知的问题Invoke-WebRequest,并Invoke-RestMethod在外壳吃响应主体时的状态代码是一个错误(4XX或5XX).听起来像你正在寻找的JSON内容正在以这种方式蒸发.您可以使用获取catch块中的响应主体$_.Exception.Response.GetResponseStream()
try {
Invoke-RestMethod "https://api.mysite.com/the/endpoint" `
-Body (ConvertTo-Json $data) `
-ContentType "application/json" `
-Headers $DefaultHttpHeaders `
-Method Post
}
catch {
$streamReader = [System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream())
$ErrResp = $streamReader.ReadToEnd() | ConvertFrom-Json
$streamReader.Close()
}
$ErrResp
Run Code Online (Sandbox Code Playgroud)
Ada*_*ski 11
根据Invoke-RestMethod文档,cmdlet可以根据收到的内容返回不同的类型.将cmdlet输出分配给变量($resp = Invoke-RestMethod (...)),然后检查类型是否为HtmlWebResponseObject($resp.gettype()).然后,您将拥有许多可供您使用的属性,例如BaseResponse,Content和StatusCode.
如果$resp是其他类型(字符串,psobject,在这种情况下很可能为null),似乎错误消息The remote server returned an error: (400) Bad Request是响应主体,只从html中剥离(我在我的一些方法上测试过这个),甚至可能被截断.如果要提取它,请使用common参数运行cmdlet以存储错误消息:Invoke-RestMethod (...) -ErrorVariable RespErr 并且您将其置于$RespErr变量中.
编辑:
好的,我明白了,很明显:).Invoke-RestMethod抛出一个错误,所以让我们抓住它:
try{$restp=Invoke-RestMethod (...)} catch {$err=$_.Exception}
$err | Get-Member -MemberType Property
TypeName: System.Net.WebException
Name MemberType Definition
---- ---------- ----------
Message Property string Message {get;}
Response Property System.Net.WebResponse Response {get;}
Status Property System.Net.WebExceptionStatus Status {get;}
Run Code Online (Sandbox Code Playgroud)
这就是您所需要的一切,尤其是在WebResponse对象中.我列出了3个引人注目的属性,还有更多.此外,如果您存储$_而不是$_.Exception可能有一些属性PowerShell已经为您提取,但我不期望没有任何更有意义的.Exception.Response.
shy*_*am_ 10
在我的情况下,$RespErr 将提供有关 BadRequest 的更多详细信息
$responce = Invoke-RestMethod -Uri https://localhost:44377/explore/v2/Content -Method Post -Body $PostData -Headers $header -ErrorVariable RespErr;
Run Code Online (Sandbox Code Playgroud)
$RespErr;
{ "error":{ "code":"","message":"The FavoriteName field is required." } }
Run Code Online (Sandbox Code Playgroud)
看起来它只适用于本地主机,我尝试使用我的实际服务器它不起作用。
另一种尝试的方法是这个
try{
$response = ""
$response = Invoke-WebRequest -Uri https://contentserverint-mhdev.azurewebsites.net/apis/explore/v2/Content?overwrite=true -Method Post -Body $PostData -Headers $header -ErrorVariable RespErr
#$response = Invoke-RestMethod -Uri https://localhost:44377/explore/v2/Content?overwrite=true -Method Post -Body $PostData -Headers $header -ErrorVariable RespErr
Write-Host "Content created with url="$response.value[0]
}
catch [System.Net.WebException] {
$respStream = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($respStream)
$respBody = $reader.ReadToEnd() | ConvertFrom-Json
$respBody;
}
Run Code Online (Sandbox Code Playgroud)
无论是 200 还是 400,都可以毫无异常地获得 HTTP 响应:
\nPowershell 7 推出-SkipHttpErrorCheck
它适用于Invoke-WebRequest和Invoke-RestMethod:
PS> $res = Invoke-WebRequest -SkipHttpErrorCheck -Method POST https://login.microsoftonline.com/does-not-exist/oauth2/token\nPS> $res \n \nStatusCode : 400 \nStatusDescription : BadRequest \nContent : {"error":"invalid_request","error_description":"AADSTS900144: The request body must contain the following parameter:\n \'grant_type\'.\\r\\nTrace ID: f40877fd-ae34-4b95-a8d4-c7b8ba613801\\r\\nCorrelation ID: \xe2\x80\xa6\nRawContent : HTTP/1.1 400 BadRequest\n Cache-Control: no-store, no-cache\n Pragma: no-cache\n Strict-Transport-Security: max-age=31536000; includeSubDomains\n X-Content-Type-Options: nosniff\n P3P: CP="DSP CUR OTPi IND OTRi\xe2\x80\xa6\nHeaders : {[Cache-Control, System.String[]], [Pragma, System.String[]], [Strict-Transport-Security, System.String[]], [X-Conte\n nt-Type-Options, System.String[]]\xe2\x80\xa6}\nImages : {}\nInputFields : {}\nLinks : {}\nRawContentLength : 503\nRelationLink : {}\nRun Code Online (Sandbox Code Playgroud)\nMS 文档说:
\n\n\n-跳过HttpErrorCheck
\n
\n此参数使 cmdlet 忽略 HTTP 错误状态并\n继续处理响应。错误响应被写入\n管道,就像它们成功一样。
\n
对我来说,它只在 Pester 上下文中工作,在阅读之前将流位置设置为 0 时。
$statusCode = $null
$responseBody = $null
try {
$response = Invoke-RestMethod -Method GET -Uri "$($apiPrefix)$($operation)" -Headers $headers
}
catch [System.Net.WebException] {
$statusCode = $_.Exception.Response.StatusCode
$respStream = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($respStream)
$reader.BaseStream.Position = 0
$responseBody = $reader.ReadToEnd() | ConvertFrom-Json
}
$statusCode | Should Be $Expected
$responseBody | Should Not Be $null
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21523 次 |
| 最近记录: |