Powershell Web请求,不会在4xx/5xx上抛出异常

jca*_*er2 68 powershell

我正在编写一个PowerShell脚本,需要发出Web请求并检查响应的状态代码.

我试过写这个:

$client = new-object system.net.webclient

$response = $client.DownloadData($url)
Run Code Online (Sandbox Code Playgroud)

以及:

$response = Invoke-WebRequest $url
Run Code Online (Sandbox Code Playgroud)

但只要网页的状态代码不是成功状态代码,PowerShell就会继续并抛出异常,而不是给我实际的响应对象.

即使加载失败,如何获取页面的状态代码?

Kei*_*ill 104

试试这个:

try { $response = Invoke-WebRequest http://localhost/foo } catch {
      $_.Exception.Response.StatusCode.Value__}
Run Code Online (Sandbox Code Playgroud)

这会引发异常,但这就是它的方式.

每条评论更新

要确保此类错误仍返回有效响应,您可以捕获类型的异常WebException并获取相关的异常Response.

由于对异常的响应是类型的System.Net.HttpWebResponse,而成功Invoke-WebRequest调用的响应是类型Microsoft.PowerShell.Commands.HtmlWebResponseObject,要从两个场景返回兼容类型,我们需要采取成功的响应BaseResponse,这也是类型System.Net.HttpWebResponse.

这个新的响应类型的状态代码是类型的枚举[system.net.httpstatuscode],而不是简单的整数,因此您必须明确地将其转换为int,或者Value__如上所述访问它的属性以获取数字代码.

#ensure we get a response even if an error's returned
$response = try { 
    (Invoke-WebRequest -Uri 'localhost/foo' -ErrorAction Stop).BaseResponse
} catch [System.Net.WebException] { 
    Write-Verbose "An exception was caught: $($_.Exception.Message)"
    $_.Exception.Response 
} 

#then convert the status code enum to int by doing this
$statusCodeInt = [int]$response.BaseResponse.StatusCode
#or this
$statusCodeInt = $response.BaseResponse.StatusCode.Value__
Run Code Online (Sandbox Code Playgroud)

  • 一个更好的方法:$ response = try {Invoke-WebRequest http:// localhost/foo} catch {$ _.Exception.Response}这样你就可以在$ response变量中得到一些东西.但请注意,失败会返回HtmlWebResponse,但成功会返回HtmlWebResponseObject.特别是,那些StatusCode是不同的类型(叹息..) (9认同)
  • 谢谢,这很有效.我没有意识到您只能从Exception对象访问Response对象. (4认同)
  • 为了避免使用不同类型的问题,对Rob的出色建议进行了一些小调整:`$ response = try {(Invoke-WebRequest -Uri'localhost / foo'-ErrorAction Stop).BaseRequest} catch [System.Net.WebException] {$ _。Exception.Response}`。即,获取BaseRequest可以确保在成功和错误情况下,我们都能获得HttpWebReqponse。添加`[System.Net.WebException]`确保我们仅以这种方式捕获相关的异常/不会意外清除其他类型的问题。 (3认同)
  • 但是在这种情况下如何获得响应内容呢? (2认同)

Mar*_*ski 10

由于 Powershell 7.0 版Invoke-WebRequest具有-SkipHttpErrorCheckswitch 参数。

-SkipHttpErrorCheck

此参数会导致 cmdlet 忽略 HTTP 错误状态并继续处理响应。错误响应被写入管道,就像它们成功一样。

此参数是在 PowerShell 7 中引入的。

文档 拉取请求

  • 也在“Invoke-RestMethod”上 (2认同)

小智 7

-SkipHttpErrorCheck是 PowerShell 7+ 的最佳解决方案,但如果您还不能使用它,那么这里有一个简单的替代方案,对于交互式命令行 Poweshell 会话很有用。

\n\n

当您看到 404 响应的错误描述时,即

\n\n
\n

远程服务器返回错误:(404) 未找到。

\n
\n\n

然后您可以通过输入以下内容从命令行查看“最后一个错误”:

\n\n
$Error[0].Exception.Response.StatusCode\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者

\n\n
$Error[0].Exception.Response.StatusDescription\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者您想从“Response\xe2\x80\x99”对象中了解的任何其他信息。

\n