Yêu cầu web Powershell mà không đưa ra ngoại lệ trên 4xx / 5xx


82

Tôi đang viết tập lệnh powershell cần thực hiện yêu cầu web và kiểm tra mã trạng thái của phản hồi.

Tôi đã thử viết cái này:

$client = new-object system.net.webclient

$response = $client.DownloadData($url)

cũng như điều này:

$response = Invoke-WebRequest $url

nhưng bất cứ khi nào trang web có mã trạng thái không phải là mã trạng thái thành công, PowerShell sẽ tiếp tục và ném một ngoại lệ thay vì cung cấp cho tôi đối tượng phản hồi thực tế.

Làm cách nào để lấy mã trạng thái của trang ngay cả khi nó không tải được?


Điều này làm việc cho tôi docs.microsoft.com/en-us/powershell/module/... Ví dụ 7: Catch thông điệp không thành công từ Invoke-WebRequest
user3520245

Câu trả lời:


121

Thử đi:

try { $response = Invoke-WebRequest http://localhost/foo } catch {
      $_.Exception.Response.StatusCode.Value__}

Thật là một điều ngớ ngẩn khi điều này ném ra một ngoại lệ nhưng nó là như vậy.

Cập nhật mỗi nhận xét

Để đảm bảo rằng các lỗi như vậy vẫn trả về phản hồi hợp lệ, bạn có thể nắm bắt các loại ngoại lệ đó WebExceptionvà tìm nạp liên quan Response.

Vì phản hồi trên ngoại lệ là loại System.Net.HttpWebResponse, trong khi phản hồi từ Invoke-WebRequestcuộc gọi thành công là loại Microsoft.PowerShell.Commands.HtmlWebResponseObject, để trả về loại tương thích từ cả hai tình huống, chúng ta cần lấy phản hồi thành công BaseResponse, cũng thuộc loại System.Net.HttpWebResponse.

Mã trạng thái của loại phản hồi mới này là một kiểu enum [system.net.httpstatuscode], thay vì một số nguyên đơn giản, vì vậy bạn phải chuyển đổi nó thành int hoặc truy cập thuộc Value__tính của nó như được mô tả ở trên để lấy mã số.

#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__

5
Cảm ơn, điều đó đã hiệu quả. Tôi không nhận ra rằng bạn chỉ có thể truy cập đối tượng Phản hồi từ đối tượng Ngoại lệ.
jcarpenter2

1
Vâng, việc truy cập số mã thực tế hơi khó khăn. :-)
Keith Hill

Mục đích của tôi là sử dụng mã này từ Chris Wahl, wahlnetwork.com/2015/02/19/…
FoxDeploy 14/10/16

11
Một cách tốt hơn một chút: $ response = try {Invoke-WebRequest localhost / foo } catch {$ _. Exception.Response} Bằng cách đó, bạn nhận được thứ gì đó trong biến $ response trong cả hai trường hợp. Nhưng lưu ý rằng thất bại trả về HtmlWebResponse, nhưng thành công trả về HtmlWebResponseObject. Đặc biệt, Mã trạng thái trên đó là các loại khác nhau (thở dài ..)
Rob Cannon

4
Một số điều chỉnh nhỏ để gợi ý tuyệt vời của Rob, để tránh các vấn đề với các loại khác nhau: $response = try { (Invoke-WebRequest -Uri 'localhost/foo' -ErrorAction Stop).BaseRequest } catch [System.Net.WebException] { $_.Exception.Response }. Tức là tìm nạp BaseRequestđảm bảo rằng trong cả trường hợp thành công và lỗi, chúng tôi đều gặp phải HttpWebReqponse. Việc thêm [System.Net.WebException]đảm bảo chúng tôi chỉ nắm bắt các ngoại lệ có liên quan theo cách này / không vô tình làm phát sinh các loại vấn đề khác.
JohnLBevan

6

Kể từ phiên bản Powershell 7.0 Invoke-WebRequest-SkipHttpErrorChecktham số chuyển đổi.

-SkipHttpErrorCheck

Tham số này khiến lệnh ghép ngắn bỏ qua các trạng thái lỗi HTTP và tiếp tục xử lý các phản hồi. Các phản hồi lỗi được ghi vào đường dẫn giống như khi chúng thành công.

Tham số này đã được giới thiệu trong PowerShell 7.

yêu cầu kéo tài liệu


0

-SkipHttpErrorCheck là giải pháp tốt nhất cho PowerShell 7+, nhưng nếu bạn chưa thể sử dụng thì đây là một giải pháp thay thế đơn giản hữu ích cho các phiên Poweshell dòng lệnh, tương tác.

Khi bạn thấy mô tả lỗi cho phản hồi 404, tức là

Máy chủ từ xa trả về lỗi: (404) Không tìm thấy.

Sau đó, bạn có thể thấy 'lỗi cuối cùng' từ dòng lệnh bằng cách nhập vào:

$Error[0].Exception.Response.StatusCode

Hoặc là

$Error[0].Exception.Response.StatusDescription

Hoặc bất kỳ điều gì khác bạn muốn biết từ đối tượng `` Phản hồi ''.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.