รหัสข้อผิดพลาด HTTP 400 BAD ร้องขอหมายถึงอะไร


346

ฉันมีคำขอ JSON ที่ฉันโพสต์ไปยัง URL HTTP

นี้ควรได้รับการปฏิบัติในฐานะ400ที่requestedResourceข้อมูลมีอยู่ แต่"Roman"เป็นค่าที่ไม่ถูกต้องสำหรับข้อมูลนี้?

[{requestedResource:"Roman"}] 

นี้ควรได้รับการปฏิบัติในฐานะ400ที่"blah"สนามไม่ได้อยู่ที่ทั้งหมดหรือไม่

[{blah:"Roman"}]

34
บางที402ถ้าพวกเขาต้องการที่จะสามารถส่งค่าที่Romanพวกเขาเพียงต้องการที่จะจ่ายเงินให้คุณมากขึ้น :)
เจสัน Sperske

สถานการณ์จริงที่ฉันเห็นสิ่งนี้ - ฉันทำการโทรด้วย PUT เพื่อเพิ่มข้อมูล ฉันทำการโทรอีกครั้งโดยใช้เนื้อความคำขอเดียวกันและได้ 400 ซึ่งบอกว่ามีการประมวลผลคำขอก่อนหน้านี้แล้ว เป็นเรื่องปกติที่ระบบของเราจะใช้เวลาในการเพิ่มข้อมูล
MasterJoe2

คำตอบ:


361

400 หมายความว่าคำขอมีรูปแบบไม่ถูกต้อง กล่าวอีกนัยหนึ่งสตรีมข้อมูลที่ลูกค้าส่งไปยังเซิร์ฟเวอร์ไม่ได้ปฏิบัติตามกฎ

ในกรณีของ REST API ที่มีเพย์โหลด JSON ปกติแล้วจะเป็น 400 และถูกต้องฉันจะบอกว่าใช้เพื่อระบุว่า JSON นั้นไม่ถูกต้องในบางวิธีตามข้อกำหนด API สำหรับบริการ

โดยตรรกะนั้นทั้งสถานการณ์ที่คุณระบุควรเป็น 400

ลองจินตนาการว่านี่คือ XML แทนที่จะเป็น JSON ในทั้งสองกรณี XML จะไม่ผ่านการตรวจสอบความถูกต้องของสคีมาเนื่องจากองค์ประกอบที่ไม่ได้กำหนดหรือค่าองค์ประกอบที่ไม่เหมาะสม นั่นจะเป็นการร้องขอที่ไม่ดี ข้อตกลงเดียวกันที่นี่


3
ฉันเห็นด้วยกับคุณถึง "ตามตรรกะแล้วสถานการณ์ทั้งสองที่คุณระบุควรเป็น 400" ฉันไม่คิดว่าเนื้อหาของ JSON ควรมีความสำคัญที่นี่ เมื่อคุณพูดผิดรูปแบบฉันต้องการที่จะเชื่อว่าปัญหาที่อยู่ในรูปแบบของข้อมูลที่คุณส่งตัวอย่างเช่นถ้าคุณข้ามเขตข้อมูลใน JSON คุณควรได้รับ 400
Geethanga

2
มีชุดที่ดีของรหัสการตอบสนองที่เหลือเป็นที่restapitutorial.com/httpstatuscodes.html นอกจากนี้ยังอาจขึ้นอยู่กับว่าคุณต้องการจัดการคำขอที่ถูกต้องเช่นวิธี 406 (ไม่ยอมรับได้) หรือไม่อนุญาต 405 อย่างไรก็ตาม 400 เหมาะสมเนื่องจาก "เซิร์ฟเวอร์ไม่สามารถเข้าใจคำขอเนื่องจากไวยากรณ์ผิดรูปแบบไคลเอ็นต์ไม่ควรทำซ้ำการร้องขอโดยไม่มีการแก้ไข"
Andrew Scott Evans

3
ดังนั้น"เซิร์ฟเวอร์ไม่สามารถเข้าใจคำขอเนื่องจากไวยากรณ์ผิดรูปแบบ"สามารถเป็นหนึ่งในคำขอ (ตัวอย่างเช่นหนึ่งในส่วนหัว HTTP ที่มีรูปแบบไม่ถูกต้อง) หรือข้อมูลที่ดำเนินการโดยคำขอ (ตัวอย่างเช่นค่า JSON หายไป) ?
MC Emperor

2
Vidya กล่าวว่า "XML จะไม่มีวันผ่านการตรวจสอบสคีมา" ชี้ให้เห็นว่า XML parsers แยกความแตกต่างระหว่างเอกสารที่มีรูปแบบที่ดี (เช่นเสียง syntactically) และถูกต้อง (เช่นเสียง semantically เช่นตาม schema) คำอธิบายของรหัส 400 คือ "เซิร์ฟเวอร์ไม่สามารถเข้าใจคำขอได้เนื่องจากไวยากรณ์ผิดรูปแบบ " - ดังนั้นจึงไม่ควรใช้สำหรับข้อผิดพลาดในการตรวจสอบความถูกต้อง imho
Martin Lie

@Vidya stackoverflow.com/questions/42851301/ลองดูที่ข้อผิดพลาดนี้ฉันกำลังเผชิญปัญหาเดียวกันกับข้อผิดพลาดนี้หากคุณรู้โปรดช่วยฉันด้วย
Mohan Gopi

74

จากw3.org

10.4.1 400 คำขอไม่ถูกต้อง

เซิร์ฟเวอร์ไม่สามารถเข้าใจการร้องขอได้เนื่องจากไวยากรณ์ผิดรูปแบบ ลูกค้าไม่ควรทำซ้ำการร้องขอโดยไม่มีการดัดแปลง


10
ความถูกต้องในการส่งคืนข้อผิดพลาด 400 ไม่ได้ขึ้นอยู่กับเขตข้อมูลเทียบกับค่า แต่การร้องขอโดยรวม ผมคิดว่า HTTP 400 เป็นวิธีที่ดีที่จะไป
เจสัน Sperske

คุณหมายความว่ามีการตอบสนอง 400 ครั้งเพื่อบอกลูกค้าว่ามีอะไรเช่น url ส่วนหัวเนื้อหา ฯลฯ ในคำขออาจผิดและไม่ใช่แค่เนื้อหา
MasterJoe2

3
ดีสำหรับ url รหัสที่ถูกต้องคือ 404 สำหรับส่วนหัวฉันเดาว่ามันเป็นการโยน 403 (ต้องห้าม) ดูเหมือนว่าวิธีที่ถูกต้องที่จะไปถ้าส่วนหัวปฏิเสธรหัสประจำตัว แต่จะเกิดอะไรขึ้นถ้าส่วนหัวกำหนดรูปแบบผลลัพธ์ เกี่ยวกับเส้นทางเดียวที่ฉันคิดว่าเหมาะสมสำหรับ 400 อยู่ในสถานการณ์ที่มีการร้องขอการกระทำที่ไม่สมเหตุสมผลและไม่ควรทำซ้ำ ฉันเขียนคำตอบนี้เมื่อ 4 ปีที่แล้ววันนี้ฉันรู้สึกว่าแม้แต่ข้อผิดพลาดควรกลับมา 200 และข้อผิดพลาดนั้นควรนำไปใช้กับการส่ง http เท่านั้นและไม่ใช่ส่วนของข้อมูล
Jason Sperske

1
คำตอบนี้ครอบคลุมถึงสิ่งนี้มากมายแม้ว่าฉันจะยังไม่ได้อ่านแผนภูมิทั้งหมด แต่stackoverflow.com/a/34324179/16959
Jason Sperske

@JasonSperske ตัวโหลดบาลานซ์พร็อกซีและมิดเดิลแวร์อื่น ๆ มักใช้รหัสสถานะเพื่อช่วยในการกำหนดเส้นทางรายงานและซ่อมแซม โชคดีที่รหัสเช่น "422" มีความชัดเจนเกี่ยวกับเพย์โหลดดังนั้นจึงมีห้องในสเป็คสำหรับรหัสสถานะเพย์โหลด
Erik Aronesty

53

การเลือกรหัสตอบกลับ HTTP นั้นค่อนข้างง่ายและสามารถอธิบายได้ด้วยกฎง่ายๆ ส่วนที่ยุ่งยากเท่านั้นที่มักถูกลืมคือย่อหน้า 6.5 จาก RFC 7231:

ยกเว้นเมื่อตอบสนองต่อคำขอ HEAD เซิร์ฟเวอร์ SHOULD จะส่งตัวแทนที่มีคำอธิบายเกี่ยวกับสถานการณ์ข้อผิดพลาดและไม่ว่าจะเป็นเงื่อนไขชั่วคราวหรือถาวร

กฎมีดังนี้:

  1. หากคำขอประสบความสำเร็จให้ส่งคืนรหัส 2xx (3xx สำหรับการเปลี่ยนเส้นทาง) หากมีข้อผิดพลาดตรรกะภายในบนเซิร์ฟเวอร์ให้ส่งคืน 5xx หากมีสิ่งผิดปกติในคำขอของลูกค้าให้ส่งคืนรหัส 4xx
  2. ดูรหัสการตอบสนองที่มีอยู่จากหมวดหมู่ที่เลือก หากหนึ่งในนั้นมีชื่อที่ตรงกับสถานการณ์ของคุณคุณสามารถใช้มัน มิฉะนั้นเพียงใช้ทางเลือกกลับไปที่รหัส x00 (200, 400, 500) หากคุณสงสัยให้เลือกรหัส x00
  3. ส่งคืนคำอธิบายข้อผิดพลาดในเนื้อหาการตอบกลับ สำหรับรหัส 4xx จะต้องมีข้อมูลเพียงพอสำหรับนักพัฒนาไคลเอนต์เพื่อทำความเข้าใจเหตุผลและแก้ไขไคลเอ็นต์ สำหรับ 5xx เนื่องจากเหตุผลด้านความปลอดภัยจะต้องไม่มีการเปิดเผยรายละเอียด
  4. หากลูกค้าต้องการแยกแยะข้อผิดพลาดที่แตกต่างกันและมีปฏิกิริยาที่แตกต่างกันขึ้นอยู่กับรูปแบบนั้นให้กำหนดรูปแบบข้อผิดพลาดที่เครื่องอ่านได้และขยายได้และใช้งานได้ทุกที่ใน API ของคุณ เป็นวิธีปฏิบัติที่ดีที่จะทำให้เกิดขึ้นตั้งแต่เริ่มต้น
  5. โปรดทราบว่าผู้พัฒนาไคลเอนต์อาจทำสิ่งที่แปลกและลองแยกสตริงที่คุณกลับมาเป็นคำอธิบายที่มนุษย์อ่านได้ และโดยการเปลี่ยนสตริงคุณจะทำลายลูกค้าที่เขียนไม่ดีเช่นนั้น ให้คำอธิบายที่เครื่องอ่านได้เสมอและพยายามหลีกเลี่ยงการรายงานข้อมูลเพิ่มเติมเป็นข้อความ

ดังนั้นในกรณีของคุณฉันจะส่งคืนข้อผิดพลาด 400 ครั้งและสิ่งนี้หากได้รับ "Roman" จากการป้อนข้อมูลของผู้ใช้และลูกค้าต้องมีปฏิกิริยาเฉพาะ:

{
    "error_type" : "unsupported_resource",
    "error_description" : "\"Roman\" is not supported"
}

หรือข้อผิดพลาดทั่วไปมากขึ้นหากสถานการณ์ดังกล่าวเป็นข้อผิดพลาดเชิงตรรกะที่ไม่ดีในลูกค้าและไม่คาดว่าจะเว้นแต่ว่านักพัฒนาทำอะไรผิด:

{
    "error_type" : "malformed_json",
    "error_description" : "\"Roman\" is not supported for \"requestedResource\" field"
}

21

ไม่ว่าในกรณีใด ๆ "ไวยากรณ์ผิดรูปแบบ" มันเป็นความหมายที่ผิด ดังนั้น IMHO a 400 จึงไม่เหมาะสม แทนที่จะเป็นการดีที่จะส่งคืน 200 พร้อมกับข้อผิดพลาดบางอย่างเช่น{ "error": { "message": "Unknown request keyword" } }หรืออะไรก็ตาม

พิจารณาเส้นทางการประมวลผลของลูกค้า ข้อผิดพลาดในไวยากรณ์ (เช่น JSON ที่ไม่ถูกต้อง) เป็นข้อผิดพลาดในตรรกะของโปรแกรมหรืออีกนัยหนึ่งคือข้อบกพร่องของการเรียงลำดับบางอย่างและควรได้รับการจัดการตามวิธีที่คล้ายกับ 403 พูด; กล่าวอีกอย่างคือมีบางอย่างไม่ดีเกิดขึ้น

ข้อผิดพลาดในค่าพารามิเตอร์ในมืออื่น ๆ ที่เป็นข้อผิดพลาดของความหมายอาจเนื่องมาจากการพูดว่าการป้อนข้อมูลของผู้ใช้ตรวจสอบไม่ดี ไม่ใช่ข้อผิดพลาด HTTP (แม้ว่าฉันคิดว่าอาจเป็น 422) เส้นทางการประมวลผลจะแตกต่างกัน

ตัวอย่างเช่นใน jQuery ฉันไม่ต้องการเขียนตัวจัดการข้อผิดพลาดเดียวที่เกี่ยวข้องกับทั้งสองอย่างเช่น 500 และข้อผิดพลาดทางความหมายเฉพาะของแอป เฟรมเวิร์กอื่น ๆ Ember สำหรับหนึ่งยังจัดการกับข้อผิดพลาด HTTP เช่น 400 และ 500 เหมือนกันกับความล้มเหลวของไขมันขนาดใหญ่ซึ่งต้องการให้โปรแกรมเมอร์ตรวจสอบสิ่งที่เกิดขึ้นและแตกสาขาขึ้นอยู่กับว่าเป็นข้อผิดพลาด


4
+1, Pใน HTTP หมายถึงProtocolและหากการตอบสนองเป็นข้อผิดพลาด HTTP ควรเป็นปัญหาระดับต่ำ ฉันได้หลีกเลี่ยงความซับซ้อนของรหัสจำนวนมากในช่วงหลายปีที่ผ่านมาโดยใช้วิธีที่อธิบายโดย torazaburo จะมีความเจ็บปวดน้อยลงในพื้นที่ REST ถ้าเราเขียนโค้ดที่ยืดหยุ่นแทนการระเบิดด้วยข้อผิดพลาด HTTP บ่อยครั้ง
Dem Pilafian

25
200 หมายความว่ามีการประมวลผลคำขอดังนั้นตรรกะความสำเร็จปกติควรดำเนินการบนไคลเอนต์ ที่นี่เรามีข้อผิดพลาดอย่างแน่นอนดังนั้นการตอบกลับจึงไม่มีรหัส 2xx หรือ 3xx ไม่สามารถเป็น 5xx ได้เนื่องจากเป็นข้อผิดพลาดฝั่งเซิร์ฟเวอร์และเรามีข้อผิดพลาดทางฝั่งไคลเอ็นต์ ดังนั้นต้องเป็นข้อผิดพลาด 4xx แต่คำอธิบายข้อผิดพลาดในเนื้อหาของการตอบกลับเป็นสิ่งที่ถูกต้องและเป็นวิธีที่แนะนำโดยข้อกำหนด HTTP
Alexey Guseynov

422 จะดีกว่าสำหรับคนตัดไม้ผู้รับมอบฉันทะและเครื่องมืออื่น ๆ
Erik Aronesty

16

การใช้400รหัสสถานะเพื่อจุดประสงค์อื่นใดที่นอกเหนือจากการระบุว่าคำขอนั้นมีรูปแบบไม่ถูกต้อง

หาก payload คำขอมีลำดับไบต์ที่ไม่สามารถแยกวิเคราะห์ได้เป็นapplication/json(หากเซิร์ฟเวอร์คาดว่า dataformat นั้น) รหัสสถานะที่เหมาะสมคือ415:

เซิร์ฟเวอร์ปฏิเสธที่จะให้บริการการร้องขอเพราะเอนทิตีของการร้องขออยู่ในรูปแบบที่ไม่ได้รับการสนับสนุนโดยทรัพยากรที่ร้องขอสำหรับวิธีการที่ร้องขอ

หากเพย์โหลดคำขอถูกต้องทางไวยากรณ์ แต่ไม่ถูกต้องในเชิงความหมาย422อาจใช้รหัสตอบกลับที่ไม่ได้มาตรฐานหรือ403รหัสสถานะมาตรฐาน:

เซิร์ฟเวอร์เข้าใจคำขอ แต่ปฏิเสธที่จะปฏิบัติตาม การอนุญาตจะไม่ช่วยและไม่ควรทำซ้ำการร้องขอ


3
ไม่ 415 ใช้สำหรับเมื่อเอนทิตีถูกอ้างว่าเป็นประเภทที่ไม่ถูกต้องเช่นimage/gifแทนที่จะtext/json เป็น Content-Type:ส่วนหัว - สันนิษฐานว่าสิ่งนี้ยังสามารถใช้งานได้หากองค์ประกอบของ multipart มีประเภทที่ไม่ถูกต้องโปรดดูtools.ietf.org/html/rfc4918ซึ่งจะกล่าวถึง 422 สำหรับการสนทนาเพิ่มเติม
Jasen

8

คิดเกี่ยวกับความคาดหวัง

ในฐานะลูกค้าแอปคุณคาดหวังว่าจะมีบางอย่างผิดปกติทางฝั่งเซิร์ฟเวอร์ หากเซิร์ฟเวอร์จำเป็นต้องโยนข้อผิดพลาดเมื่อblahหายไปหรือrequestedResourceค่าไม่ถูกต้องกว่าข้อผิดพลาด 400 จะเหมาะสม


5

ในฐานะที่เป็นส่วนเสริมสำหรับผู้ที่อาจพบปัญหาเดียวกันกับของฉันฉันใช้$.ajaxเพื่อโพสต์ข้อมูลแบบฟอร์มไปยังเซิร์ฟเวอร์และฉันยังได้รับ400ข้อผิดพลาดในตอนแรก

สมมติว่าฉันมีตัวแปรจาวาสคริปต์

var formData = {
    "name":"Gearon",
    "hobby":"Be different"
    }; 

อย่าใช้ตัวแปรformDataโดยตรงเป็นค่าของคีย์dataดังนี้:

$.ajax({
    type: "post",
    dataType: "json",
    url: "http://localhost/user/add",
    contentType: "application/json",
    data: formData,
    success: function(data, textStatus){
        alert("Data: " + data + "\nStatus: " + status); 
    }
});

ใช้ JSON.stringify แทนเพื่อแค็ปซูลformDataดังนี้:

$.ajax({
    type: "post",
    dataType: "json",
    url: "http://localhost/user/add",
    contentType: "application/json",
    data: JSON.stringify(formData),
    success: function(data, textStatus){
        alert("Data: " + data + "\nStatus: " + status); 
    }
});

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


ฉันคิดว่า OP ขอให้ 400 เป็นรหัสข้อผิดพลาดที่เหมาะสมเพื่อส่งคืนหรือไม่เมื่อคำขอไม่ผิดรูปแบบ แต่อย่างใดไม่ตรงตามข้อกำหนดระดับแอปพลิเคชัน เช่นคุณสามารถสร้างเครื่องคิดเลขออนไลน์ที่คุณส่งสมการเป็น JSON หากคุณส่ง json ที่ถูกต้องของการเพิ่มตัวเลขด้วยสตริงแสดงว่าคำขอนั้นถูกต้อง แต่ไม่ถูกต้องเชิงความหมายของแอปพลิเคชัน อย่างไรก็ตามเบราว์เซอร์ของคุณจะเห็นคำขอเป็น 'ไม่ดี'
Jeppe

4

ก่อนอื่นตรวจสอบ URL ว่ามันอาจจะผิดถ้ามันถูกต้องแล้วตรวจสอบคำขอร่างกายที่คุณกำลังส่งสาเหตุที่เป็นไปได้คือการร้องขอที่คุณกำลังส่งไม่มีไวยากรณ์ที่ถูกต้อง

หากต้องการทำอย่างละเอียดตรวจสอบอักขระพิเศษในสตริงคำขอ ถ้าเป็น (อักขระพิเศษ) ที่ใช้นี่เป็นสาเหตุของข้อผิดพลาดนี้

ลองคัดลอกคำขอและวิเคราะห์ข้อมูลแท็กแต่ละรายการ


ฉันได้รับข้อผิดพลาด http 400 ฉันตรวจสอบว่าคำขอของฉันมีอักขระพิเศษบางตัว ในการแก้ไขนั้นฉันผ่านชุดอักขระ = UTF-8 ในประเภทเนื้อหา
Kislay Kishore
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.