Curl เพื่อส่งคืนรหัสสถานะ http พร้อมกับการตอบกลับ


119

ฉันใช้ curl เพื่อรับส่วนหัว http เพื่อค้นหารหัสสถานะ http และส่งคืนการตอบสนอง ฉันได้รับส่วนหัว http ด้วยคำสั่ง

curl -I http://localhost

เพื่อรับการตอบสนองฉันใช้คำสั่ง

curl http://localhost

ทันทีที่ใช้แฟล็ก -I ฉันจะได้รับเฉพาะส่วนหัวและการตอบสนองจะไม่มีอีกต่อไป มีวิธีรับทั้งการตอบสนอง http และรหัสสถานะส่วนหัว / http ในคำสั่งเดียวหรือไม่?


1
นี่คือตัวอย่างข้อมูลที่มีประโยชน์มากgist.github.com/maxcnunes/9f77afdc32df354883df
rocketspacer

คำตอบ:


116

ฉันสามารถหาวิธีแก้ปัญหาได้โดยดูที่ curl doc ซึ่งระบุให้ใช้-สำหรับเอาต์พุตเพื่อรับเอาต์พุตเป็น stdout

curl -o - http://localhost

เพื่อให้ได้รับการตอบกลับด้วยโค้ดส่งคืน http ฉันสามารถทำได้

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

15
-iหรือคุณต้องการใช้ หรือบางที-vถ้าคุณชอบข้อมูลเพิ่มเติมด้วย
Daniel Stenberg

2
ขอบคุณ @DanielStenberg คำตอบที่ยอมรับไม่ได้ผลสำหรับฉันเพียงแค่ใช้ -i ก็ใช้ได้ผล
Alejandro Cotilla

คำสั่งที่สองของคุณหายไป -I @randominstanceOfLivingThing เว้นแต่ว่าจะเป็นตัวเลือกว่างโดยเจตนา? ไม่ได้ผลสำหรับฉันถ้าไม่มีมัน
mdo123

2
-o -Iจบลงด้วยการสร้างไฟล์ชื่อตัวอักษร ' -I' ใน CWD มีใครเห็นสิ่งนี้ไหม ทางออกคือ-o/dev/null -I
JDS

ลบ -I ฉันสังเกตเห็นและแก้ไขในขณะนี้ คุณไม่ต้องการ -I
randominstanceOfLivingThing


39

ฉันใช้คำสั่งนี้เพื่อพิมพ์รหัสสถานะโดยไม่มีเอาต์พุตอื่น ๆ นอกจากนี้จะดำเนินการเฉพาะคำขอ HEAD และทำตามการเปลี่ยนเส้นทาง (ตามลำดับ-Iและ-L)

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

ทำให้ง่ายต่อการตรวจสอบรหัสสถานะในสคริปต์สุขภาพ:

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

5
นี้ได้รับคำตอบแล้วเมื่อปีที่แล้ว คำตอบของคุณนำมาซึ่งคุณค่าใหม่อะไร? โปรดเขียนคำอธิบายสำหรับคำตอบของคุณด้วย
Maciej Jureczko

11
@MaciejJureczko - ค่าง่ายๆ สำหรับวัตถุประสงค์ในการเขียนสคริปต์คำตอบนี้เป็นคำตอบที่ดีที่สุดในบรรดาคำตอบอื่น ๆ ทั้งหมดเนื่องจากให้รหัสสถานะเดียวแทนที่จะเป็นขยะหลายบรรทัดพร้อมกับรหัสสถานะดังกล่าว
รวม

2
แต่ OP ระบุว่าพวกเขาต้องการทั้งรหัสสถานะและเนื้อหาตอบสนอง พวกเขารู้วิธีรับรหัสตอบกลับ (ระบุไว้ในคำถาม)
wottle

2
เมื่อใดก็ตามที่ฉันใช้curl -o -I -L -s -w "%{http_code}" http://localhostไฟล์นี้จะถูกสร้างขึ้นเรียกว่า-Iเพื่อหลีกเลี่ยงสิ่งนี้ฉันได้เพิ่มสถานที่สำหรับเอาต์พุตไฟล์โดยนัยที่-oจะไปคือ/dev/null:curl -o /dev/null -I -L -s -w "%{http_code}" http://localhost
เกิดขึ้นเมื่อ

HEAD จะไม่ให้ผลลัพธ์เดียวกันกับคำขอเสมอไปขึ้นอยู่กับเซิร์ฟเวอร์ว่าจะตอบสนองอย่างไร นี่จึงไม่ใช่คำตอบจริงๆ
Eddie

28

ฉันพบคำถามนี้เพราะฉันต้องการให้ทั้งสองตอบสนองและเนื้อหาเพื่อเพิ่มการจัดการข้อผิดพลาดบางอย่างสำหรับผู้ใช้

คุณสามารถพิมพ์รหัสสถานะ HTTP เพื่อ std out และเขียนเนื้อหาไปยังไฟล์อื่นได้

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

วิธีนี้ให้คุณใช้ตรรกะเพื่อตัดสินใจว่าการตอบสนองนั้นคุ้มค่ากับการประมวลผลหรือไม่

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 คืออะไร? ฉันไม่เข้าใจสิ่งนี้ต้องการคำอธิบายเพิ่มเติมกรุณา
Alexander Mills

อธิบายไว้ข้างต้นหมายถึงรหัสสถานะ HTTP - developer.mozilla.org/en-US/docs/Web/HTTP/Status
Eddie

24

-iตัวเลือกหนึ่งที่คุณต้องการ:

curl -i http://localhost

-i, - รวมส่วนหัวของโปรโตคอลในเอาต์พุต (H / F)

หรือคุณสามารถใช้ตัวเลือก verbose:

curl -v http://localhost

-v, --verbose ทำให้การดำเนินการเป็นที่พูดถึงมากขึ้น


16

ฉันได้ใช้สิ่งนี้:

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

เพื่อรับสถานะ HTTP

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

เพื่อให้ได้ร่างกายตอบสนองฉันใช้สิ่งนี้

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

8

คำสั่งนี้

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

จะได้รับร่างกายและสถานะที่คั่นด้วยเครื่องหมายจุลภาค คุณสามารถแยกมันออกเพื่อนำออก

คุณสามารถเปลี่ยนตัวคั่นได้ตามต้องการ


2
คำใบ้ที่ดี! เป็นไปได้หรือไม่ที่จะเพิ่มรหัสสถานะที่ด้านหน้าเอาต์พุต
Psychozoic

6

สำหรับการใช้งานแบบเป็นโปรแกรมฉันใช้สิ่งต่อไปนี้:

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

แสดงผลลัพธ์ต่อไปนี้:

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

5

นี่เป็นวิธีดึงเนื้อหา "AND" รหัสสถานะและจัดรูปแบบเป็น json ที่เหมาะสมหรือรูปแบบใดก็ได้ที่เหมาะกับคุณ บางคนอาจโต้แย้งว่าเป็นการใช้ตัวเลือกรูปแบบการเขียนที่ไม่ถูกต้อง แต่สิ่งนี้ใช้ได้กับฉันเมื่อฉันต้องการทั้งเนื้อความและรหัสสถานะในสคริปต์ของฉันเพื่อตรวจสอบรหัสสถานะและส่งต่อการตอบกลับจากเซิร์ฟเวอร์

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

รันโค้ดด้านบนและคุณควรได้รับ json กลับมาในรูปแบบนี้:

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

ด้วยอ็อพชันรูปแบบการเขียน -w เนื่องจาก stderr ถูกพิมพ์ก่อนคุณสามารถจัดรูปแบบผลลัพธ์ของคุณด้วย var http_code และวางเนื้อหาของการตอบสนองในค่า (body) และติดตามการปิดล้อมโดยใช้ var stdout จากนั้นเปลี่ยนเส้นทางเอาท์พุท stderr ของคุณไปที่ stdout และคุณจะสามารถรวมทั้ง http_code และเนื้อหาการตอบสนองลงในผลลัพธ์ที่เรียบร้อย


1
มีข้อผิดพลาดต่อไปนี้ - curl: unknown --write-out variable: 'stderr'และcurl: unknown --write-out variable: 'stdout'
ALex_hha

curl.haxx.se/docs/manpage.html man page แสดงตัวแปรที่พร้อมใช้งาน ไม่แน่ใจว่าทำไม curl ของคุณไม่รู้จัก stderr, curl im บน macbook จาก Linux curl doc, computerhope.com/unix/curl.htmฉันไม่เห็น stderr เป็นตัวแปรเช่นกัน บางทีนี่อาจเป็นรูปแบบของระบบปฏิบัติการ
Huy Tran

ปัญหาเดียวที่ฉันมีกับสิ่งนี้คือถ้าร่างกายของคุณมีเครื่องหมายคำพูดเช่นถ้า json ของมันร่างกายจะทำให้การตอบสนองของ json เหนือ json ไม่ถูกต้อง
theannouncer

@theannouncer ยุติธรรมเพียงพอฉันคาดหวังว่า dev จะปรับตามเนื่องจากการตอบสนองทั้งหมดจะไม่เป็นมาตรฐาน json มีบางกรณีที่ฉันต้องปรับเปลี่ยนเนื่องจากลักษณะของการตอบสนอง
Huy Tran

2

วิธีของฉันที่จะบรรลุสิ่งนี้ :

ในการรับทั้ง (ส่วนหัวและส่วนเนื้อหา) ฉันมักจะแสดงcurl -D- <url>เป็น:

$ 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"]}

สิ่งนี้จะถ่ายโอนข้อมูลส่วนหัว ( -D) ไปยัง stdout ( -) (มองหา--dump-headerในman curl )

IMHO ยังมีประโยชน์มากในบริบทนี้:

ฉันมักจะใช้jqเพื่อรับข้อมูล json นั้น (เช่นจาก API ที่เหลือบางส่วน) ในรูปแบบ แต่เป็น JQ ไม่คาดว่าจะมีส่วนหัว HTTP, เคล็ดลับคือการพิมพ์ส่วนหัวเพื่อ stderr -D/dev/stderrใช้ โปรดทราบว่าครั้งนี้เรายังใช้-sS(--silent, --show-error) เพื่อระงับตัววัดความคืบหน้า (เพราะเราเขียนไปยังไพพ์)

$ 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"
  ]
}

ฉันเดาว่าสิ่งนี้มีประโยชน์เช่นกันหากคุณต้องการพิมพ์ส่วนหัว (เพื่อการตรวจสอบอย่างรวดเร็ว) เพื่อคอนโซล แต่เปลี่ยนเส้นทางเนื้อหาไปยังไฟล์ (เช่นเมื่อไบนารีบางประเภทไม่ทำให้เทอร์มินัลของคุณสับสน):

$ 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

ระวัง: นี่ไม่เหมือนกับcurl -I <url>! ตามที่-IจะดำเนินการHEADตามคำขอไม่ใช่GETคำขอ (มองหา--headในman curlใช่: สำหรับเซิร์ฟเวอร์ HTTP ส่วนใหญ่สิ่งนี้จะให้ผลลัพธ์เหมือนกัน แต่ฉันรู้จักแอปพลิเคชันทางธุรกิจจำนวนมากที่ไม่ได้ใช้HEADคำขอเลย ;-P


0

ต่อท้ายบรรทัด "http_code: 200" ต่อท้ายจากนั้น grep สำหรับคีย์เวิร์ด "http_code:" และแยกโค้ดตอบกลับ

result=$(curl -w "\nhttp_code:%{http_code}" http://localhost)

echo "result: ${result}"   #the curl result with "http_code:" at the end

http_code=$(echo "${result}" | grep 'http_code:' | sed 's/http_code://g') 

echo "HTTP_CODE: ${http_code}"  #the http response code

ในกรณีนี้คุณยังคงสามารถใช้โหมด non-silent / verbose mode เพื่อรับข้อมูลเพิ่มเติมเกี่ยวกับคำร้องเช่น curl response body


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

1
ทำไมคุณถึงใส่สิ่งนี้ในขณะที่? กรุณาขยายความและอธิบายคำตอบของคุณ
Uberhumus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.