Cuộn tròn để trả về mã trạng thái http cùng với phản hồi


110

Tôi sử dụng curl để lấy tiêu đề http để tìm mã trạng thái http và trả lời phản hồi. Tôi nhận được các tiêu đề http bằng lệnh

curl -I http://localhost

Để nhận được phản hồi, tôi sử dụng lệnh

curl http://localhost

Ngay sau khi sử dụng cờ -I, tôi chỉ nhận được các tiêu đề và phản hồi không còn ở đó nữa. Có cách nào để nhận được cả phản hồi http và tiêu đề / mã trạng thái http trong một lệnh không?


1
Dưới đây là một đoạn rất hữu ích gist.github.com/maxcnunes/9f77afdc32df354883df
rocketspacer

Câu trả lời:


111

Tôi đã có thể tìm ra giải pháp bằng cách xem curl doc chỉ định sử dụng -cho đầu ra để lấy đầu ra thành stdout.

curl -o - http://localhost

Để nhận được phản hồi chỉ với mã trả lại http, tôi chỉ có thể làm

curl -o /dev/null -s -w "%{http_code}\n" http://localhost

12
hoặc bạn sẽ sử dụng -i. Hoặc có lẽ -vnếu bạn cũng thích một số thông tin bổ sung.
Daniel Stenberg

2
Cảm ơn @DanielStenberg. Câu trả lời được chấp nhận không hoạt động đối với tôi, chỉ đơn giản là sử dụng -i đã hoạt động.
Alejandro Cotilla 13/09/17

lệnh thứ hai của bạn bị thiếu -I @randominstanceOfLivingThing, trừ khi đó cố ý là một tùy chọn trống? Không làm việc cho tôi mà không có nó mặc dù
mdo123

2
-o -Ikết thúc việc tạo một tệp có tên theo nghĩa đen là ' -I' trong CWD. Có ai khác thấy điều này? Giải pháp cho điều đó là-o/dev/null -I
JDS

Đã xóa I. Tôi nhận thấy và sửa chữa ngay bây giờ. Bạn không cần tôi.
randominstanceOfLivingThing


36

Tôi sử dụng lệnh này để in mã trạng thái mà không cần bất kỳ đầu ra nào khác. Ngoài ra, nó sẽ chỉ thực hiện yêu cầu HEAD và thực hiện theo chuyển hướng (tương ứng -I-L).

curl -o -I -L -s -w "%{http_code}" http://localhost

Điều này giúp bạn dễ dàng kiểm tra mã trạng thái trong tập lệnh tình trạng:

sh -c '[ $(curl -o -I -L -s -w "%{http_code}" http://localhost) -eq 200 ]'

5
Điều này đã được trả lời một năm trước. Câu trả lời của bạn mang lại giá trị mới nào? Cũng xin vui lòng viết một số giải thích cho câu trả lời của bạn.
Maciej Jureczko

11
@MaciejJureczko - Giá trị rất đơn giản. Đối với mục đích kịch bản, câu trả lời này là tốt nhất trong số tất cả các câu trả lời khác, vì nó cung cấp một mã trạng thái duy nhất thay vì nhiều dòng rác cùng với mã trạng thái đã nói.
tổng

2
Nhưng OP nói rõ rằng họ muốn cả mã trạng thái và nội dung phản hồi. Họ biết làm thế nào để chỉ nhận được mã phản hồi (nêu trong câu hỏi)
wottle

2
Bất cứ khi nào tôi sử dụng này curl -o -I -L -s -w "%{http_code}" http://localhostmột tập tin được tạo có tên -I, để có được xung quanh tôi này thêm một chỗ cho đầu ra tập tin ngụ ý bởi -ođể đi, cụ thể là /dev/null:curl -o /dev/null -I -L -s -w "%{http_code}" http://localhost
Thismatters

Tuy nhiên, HEAD sẽ không phải lúc nào cũng cho ra kết quả giống như một yêu cầu, tùy thuộc vào cách họ phản hồi. Vì vậy, đây không thực sự là một câu trả lời.
Eddie

28

Tôi tìm thấy câu hỏi này vì tôi muốn CẢ PHẢI phản hồi và nội dung để thêm một số xử lý lỗi cho người dùng.

Bạn có thể in mã trạng thái HTTP để in ra và ghi nội dung vào tệp khác.

curl -s -o response.txt -w "%{http_code}" http://example.com

Điều này cho phép bạn sử dụng logic để quyết định xem phản hồi có đáng được xử lý hay không.

http_response=$(curl -s -o response.txt -w "%{http_code}" http://example.com)
if [ $http_response != "200" ]; then
    # handle error
else
    echo "Server returned:"
    cat response.txt    
fi

http_code là gì? Tôi không hiểu điều này, cần thêm xin giải thích
Alexander Mills

làm rõ ở trên, nó đề cập đến mã HTTP Status - developer.mozilla.org/en-US/docs/Web/HTTP/Status
Eddie

22

Các -itùy chọn là một trong những bạn muốn:

curl -i http://localhost

-i, --bao gồm Bao gồm các tiêu đề giao thức trong đầu ra (H / F)

Ngoài ra, bạn có thể sử dụng tùy chọn dài dòng:

curl -v http://localhost

-v, --verbose Làm cho hoạt động nói nhiều hơn


16

Tôi đã sử dụng cái này:

    request_cmd="$(curl -i -o - --silent -X GET --header 'Accept: application/json' --header 'Authorization: _your_auth_code==' 'https://example.com')"

Để nhận trạng thái HTTP

    http_status=$(echo "$request_cmd" | grep HTTP |  awk '{print $2}')
    echo $http_status

Để có được phần thân phản hồi, tôi đã sử dụng cái này

    output_response=$(echo "$request_cmd" | grep body)
    echo $output_response

8

Lệnh này

 curl http://localhost -w ", %{http_code}"

sẽ nhận được phần thân và trạng thái được phân tách bằng dấu phẩy; bạn có thể tách chúng ra để lấy chúng ra.

Bạn có thể thay đổi dấu phân cách theo ý muốn.


2
gợi ý tốt! có thể thêm mã trạng thái ở phía trước đầu ra không?
Psychozoic

6

Để sử dụng có lập trình, tôi sử dụng như sau:

curlwithcode() {
    code=0
    # Run curl in a separate command, capturing output of -w "%{http_code}" into statuscode
    # and sending the content to a file with -o >(cat >/tmp/curl_body)
    statuscode=$(curl -w "%{http_code}" \
        -o >(cat >/tmp/curl_body) \
        "$@"
    ) || code="$?"

    body="$(cat /tmp/curl_body)"
    echo "statuscode : $statuscode"
    echo "exitcode : $code"
    echo "body : $body"
}

curlwithcode https://api.github.com/users/tj

Nó hiển thị đầu ra sau:

statuscode : 200
exitcode : 0
body : {
  "login": "tj",
  "id": 25254,
  ...
}

5

Đây là một cách để truy xuất nội dung mã trạng thái "VÀ" và định dạng nó thành json thích hợp hoặc bất kỳ định dạng nào phù hợp với bạn. Một số người có thể cho rằng đó là việc sử dụng không chính xác tùy chọn định dạng ghi nhưng điều này phù hợp với tôi khi tôi cần cả mã nội dung và trạng thái trong tập lệnh của mình để kiểm tra mã trạng thái và chuyển lại phản hồi từ máy chủ.

curl -X GET -w "%{stderr}{\"status\": \"%{http_code}\", \"body\":\"%{stdout}\"}"  -s -o - https://github.com 2>&1

chạy đoạn mã trên và bạn sẽ nhận lại một json ở định dạng sau:

{
"status" : <status code>,
"body" : <body of response>
}

với tùy chọn định dạng ghi -w, vì stderr được in trước, bạn có thể định dạng đầu ra của mình bằng var http_code và đặt phần thân của phản hồi trong một giá trị (body) và theo dõi phần bao quanh bằng var stdout. Sau đó, chuyển hướng đầu ra stderr của bạn sang stdout và bạn sẽ có thể kết hợp cả http_code và phần thân phản hồi thành một đầu ra gọn gàng


1
curl: unknown --write-out variable: 'stderr'curl: unknown --write-out variable: 'stdout'
Gặp

curl.haxx.se/docs/manpage.html trang người đàn ông hiển thị biến có sẵn. không chắc tại sao stderr không được nhận dạng bởi curl của bạn, curl im trên macbook. Từ tài liệu curl Linux này, computerhope.com/unix/curl.htm , tôi cũng không thấy stderr là một biến. Có lẽ đây là một biến thể của hệ điều hành.
Huy Tran

vấn đề duy nhất tôi gặp phải với điều này là nếu nội dung của bạn có dấu ngoặc kép, chẳng hạn như nếu json của nó, nội dung sẽ thực hiện phản hồi json trên json không hợp lệ
theannouncer

đủ công bằng @theannouncer, tôi mong nhà phát triển điều chỉnh cho phù hợp vì không phải tất cả các câu trả lời đều là json tiêu chuẩn. Có một số trường hợp tôi phải điều chỉnh do bản chất của phản hồi.
Huy Tran

1

Cách của tôi để đạt được điều này :

Để có được cả hai (tiêu đề và nội dung), tôi thường thực hiện curl -D- <url>như sau:

$ curl -D- http://localhost:1234/foo
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 20:59:21 GMT

{"data":["out.csv"]}

Thao tác này sẽ kết xuất tiêu đề ( -D) thành stdout ( -) (Tìm --dump-headertrong man curl ).

IMHO cũng rất tiện dụng trong bối cảnh này:

Tôi thường sử dụng jq để định dạng dữ liệu json (ví dụ: từ một số API còn lại). Nhưng vì jq không mong đợi một tiêu đề HTTP, mẹo là in tiêu đề để stderr sử dụng -D/dev/stderr. Lưu ý rằng lần này chúng tôi cũng sử dụng -sS(--silent, --show-error) để ngăn chặn đồng hồ đo tiến trình (vì chúng tôi viết vào một đường ống).

$ curl -sSD/dev/stderr http://localhost:1231/foo | jq .
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 21:08:22 GMT

{
  "data": [
    "out.csv"
  ]
}

Tôi đoán điều này cũng có thể hữu ích nếu bạn muốn in tiêu đề (để kiểm tra nhanh) vào bảng điều khiển nhưng chuyển hướng nội dung đến một tệp (ví dụ: khi một số loại nhị phân của nó để không làm rối thiết bị đầu cuối của bạn):

$ curl -sSD/dev/stderr http://localhost:1231 > /dev/null
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 21:20:02 GMT

Hãy lưu ý: Điều này KHÔNG giống với curl -I <url>! Như -Isẽ thực hiện một HEADyêu cầu chứ không phải một GETyêu cầu (Hãy tìm --headtrong man curl . Có: Đối với hầu hết các máy chủ HTTP, điều này sẽ mang lại kết quả tương tự. Nhưng tôi biết rất nhiều ứng dụng kinh doanh không thực hiện HEADyêu cầu nào cả ;-P


-2
while : ; do curl -sL -w "%{http_code} %{url_effective}\\n" http://host -o /dev/null; done

1
Tại sao bạn lại đặt điều này trong một vòng lặp while? Hãy mở rộng và giải thích câu trả lời của bạn.
Uberhumus
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.