400 BAD yêu cầu mã lỗi HTTP có nghĩa là gì?


346

Tôi có một yêu cầu JSON mà tôi đang đăng lên URL HTTP.

Này phải được coi là 400nơi requestedResourcelĩnh vực tồn tại nhưng "Roman"là một giá trị không hợp lệ cho lĩnh vực này?

[{requestedResource:"Roman"}] 

Điều này có nên được coi là 400nơi mà "blah"trường không tồn tại?

[{blah:"Roman"}]

34
Có lẽ là 402 , nếu họ thực sự muốn có thể gửi giá trị Roman, họ chỉ cần trả cho bạn nhiều hơn :)
Jason Sperske

Một kịch bản thực tế nơi tôi thấy điều này - Tôi đã thực hiện một cuộc gọi PUT để thêm một số dữ liệu. Tôi đã thực hiện một cuộc gọi lại bằng cách sử dụng cùng một yêu cầu và nhận được 400 yêu cầu cho tôi biết rằng một yêu cầu trước đó đã được xử lý. Hệ thống của chúng tôi mất một chút thời gian để thêm dữ liệu đó.
MasterJoe2

Câu trả lời:


360

400 có nghĩa là yêu cầu không đúng. Nói cách khác, luồng dữ liệu được gửi bởi máy khách đến máy chủ không tuân theo các quy tắc.

Trong trường hợp API REST có tải trọng JSON, thông thường 400, và tôi nói chính xác, được sử dụng để chỉ ra rằng JSON không hợp lệ theo một cách nào đó theo đặc tả API cho dịch vụ.

Theo logic đó, cả hai kịch bản bạn cung cấp phải là 400.

Thay vào đó hãy tưởng tượng đây là XML chứ không phải JSON. Trong cả hai trường hợp, XML sẽ không bao giờ vượt qua xác thực lược đồ - do phần tử không xác định hoặc giá trị phần tử không phù hợp. Đó sẽ là một yêu cầu xấu. Thỏa thuận tương tự ở đây.


3
Tôi đồng ý với bạn tới "Theo logic đó, cả hai kịch bản bạn cung cấp phải là 400 giây." Tôi không nghĩ nội dung của JSON nên có vấn đề ở đây. Khi bạn nói không đúng, tôi muốn tin rằng giải quyết các vấn đề theo định dạng của dữ liệu bạn gửi, ví dụ: nếu bạn bỏ qua một trường trong JSON, bạn sẽ nhận được 400.
Geethanga

2
Có một bộ mã phản hồi REST khá tốt tại restapitutorial.com/httpstatuscodes.html . Nó cũng có thể phụ thuộc vào cách bạn muốn xử lý một yêu cầu hợp lệ, chẳng hạn như phương thức 406 (Không được chấp nhận) hoặc 405 không được phép. Tuy nhiên, 400 là phù hợp vì "Máy chủ không thể hiểu được yêu cầu do cú pháp không đúng. Máy khách KHÔNG NÊN lặp lại yêu cầu mà không sửa đổi."
Andrew Scott Evans

3
Vì vậy, "Máy chủ không thể hiểu được yêu cầu do cú pháp không đúng" có thể là một trong những yêu cầu (ví dụ: một trong các tiêu đề HTTP không đúng định dạng) hoặc dữ liệu được cung cấp bởi yêu cầu (ví dụ: thiếu giá trị JSON) ?
MC Hoàng đế

2
Vidya nói "XML sẽ không bao giờ vượt qua xác thực lược đồ". Điểm đáng chú ý là các trình phân tích cú pháp XML phân biệt giữa một tài liệu được định dạng tốt (nghĩa là âm thanh cú pháp) và hợp lệ (nghĩa là âm thanh ngữ nghĩa, ví dụ như theo một lược đồ). Mô tả của mã 400 là "máy chủ không thể hiểu được yêu cầu do cú pháp không đúng " - vì vậy không nên sử dụng nó cho các lỗi xác thực, imho.
Martin Lie

@Vidya stackoverflow.com/questions/42851301/ Hãy xem lỗi này tôi cũng gặp phải vấn đề tương tự như lỗi này nếu bạn biết xin hãy giúp tôi
Mohan Gopi

74

Từ w3.org

10.4.1 400 Yêu cầu xấu

Máy chủ không thể hiểu được yêu cầu do cú pháp không đúng. Khách hàng KHÔNG NÊN lặp lại yêu cầu mà không sửa đổi.


10
Tính chính xác của việc trả lại lỗi 400 không dựa trên một trường so với giá trị mà là toàn bộ yêu cầu. Tôi nghĩ HTTP 400 là một cách tốt để đi
Jason Sperske

Bạn có nghĩa là một phản hồi 400 được sử dụng để nói với khách hàng rằng bất cứ điều gì, ví dụ như url, tiêu đề, nội dung, v.v., trong yêu cầu có thể sai và không chỉ là cơ thể?
MasterJoe2

3
đối với url, mã chính xác là 404, đối với các tiêu đề, tôi đoán đó là một sự tung lên, 403 (bị cấm) có vẻ như là cách đúng đắn nếu các tiêu đề đang từ chối danh tính, nhưng nếu các tiêu đề đang xác định định dạng đầu ra thì sao? về con đường duy nhất tôi nghĩ cảm thấy phù hợp với 400 là trong tình huống một hành động đang được yêu cầu không có ý nghĩa và không nên lặp lại. Tôi đã viết câu trả lời này 4 năm trước, những ngày này tôi cảm thấy như các lỗi thậm chí sẽ trả về 200 và các lỗi đó chỉ nên áp dụng cho việc truyền http chứ không phải tải trọng.
Jason Sperske

1
Câu trả lời này bao gồm rất nhiều điều này, mặc dù tôi chưa đọc qua tất cả các biểu đồ nhưng stackoverflow.com/a
432324179/16959

@JasonSperske cân bằng tải, proxy và phần mềm trung gian khác thường sử dụng mã trạng thái để giúp định tuyến, báo cáo và sửa chữa. may mắn thay, các mã như "422" rõ ràng liên quan đến tải trọng, vì vậy có một số chỗ trong thông số kỹ thuật cho mã trạng thái tải trọng.
Erik Aronesty

53

Chọn mã phản hồi HTTP là một nhiệm vụ khá dễ dàng và có thể được mô tả bằng các quy tắc đơn giản. Phần khó khăn duy nhất thường bị lãng quên là đoạn 6.5 từ RFC 7231:

Ngoại trừ khi trả lời yêu cầu CHÍNH, máy chủ NÊN gửi một đại diện có giải thích về tình huống lỗi và cho dù đó là tình trạng tạm thời hay vĩnh viễn.

Các quy tắc như sau:

  1. Nếu yêu cầu thành công, hãy trả về mã 2xx (3xx để chuyển hướng). Nếu có lỗi logic bên trong trên máy chủ, thì trả về 5xx. Nếu có bất cứ điều gì sai trong yêu cầu của khách hàng, sau đó trả lại mã 4xx.
  2. Xem qua mã phản hồi có sẵn từ danh mục đã chọn. Nếu một trong số chúng có tên phù hợp với hoàn cảnh của bạn, bạn có thể sử dụng nó. Nếu không, chỉ cần dự phòng mã x00 (200, 400, 500). Nếu bạn nghi ngờ, hãy chuyển sang mã x00.
  3. Trả về mô tả lỗi trong cơ thể phản hồi. Đối với mã 4xx, nó phải chứa đủ thông tin để nhà phát triển khách hàng hiểu lý do và khắc phục ứng dụng khách. Đối với 5xx vì lý do bảo mật, không có chi tiết phải được tiết lộ.
  4. Nếu khách hàng cần phân biệt các lỗi khác nhau và có phản ứng khác nhau tùy thuộc vào lỗi đó, hãy xác định định dạng lỗi có thể đọc và mở rộng của máy và sử dụng nó ở mọi nơi trong API của bạn. Đó là thực hành tốt để làm điều đó ngay từ đầu.
  5. Hãy nhớ rằng nhà phát triển khách hàng có thể làm những điều kỳ lạ và cố gắng phân tích các chuỗi mà bạn trả lại dưới dạng mô tả có thể đọc được của con người. Và bằng cách thay đổi các chuỗi, bạn sẽ phá vỡ các khách hàng viết xấu như vậy. Vì vậy, luôn luôn cung cấp mô tả có thể đọc được máy và cố gắng tránh báo cáo thông tin bổ sung trong văn bản.

Vì vậy, trong trường hợp của bạn, tôi đã trả về 400 lỗi và đại loại như thế này nếu "Roman" được lấy từ đầu vào của người dùng và khách hàng phải có phản ứng cụ thể:

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

hoặc một lỗi chung hơn, nếu tình huống đó là lỗi logic xấu trong máy khách và không được mong đợi, trừ khi nhà phát triển đã làm gì đó sai:

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

21

Trong cả hai trường hợp là "cú pháp không đúng". Đó là ngữ nghĩa sai. Do đó, IMHO 400 là không phù hợp. Thay vào đó, sẽ là thích hợp để trả về 200 cùng với một số loại đối tượng lỗi như { "error": { "message": "Unknown request keyword" } }hoặc bất cứ điều gì.

Xem xét (các) đường dẫn xử lý máy khách. Một lỗi trong cú pháp (ví dụ JSON không hợp lệ) là một lỗi trong logic của chương trình, nói cách khác là một lỗi thuộc loại nào đó và nên được xử lý tương ứng, theo cách tương tự như 403, nói; nói cách khác, một cái gì đó xấu đã đi sai.

Mặt khác, một lỗi trong một giá trị tham số là lỗi về ngữ nghĩa, có lẽ do đầu vào của người dùng được xác nhận kém. Đây không phải là lỗi HTTP (mặc dù tôi cho rằng đó có thể là lỗi 422). Con đường xử lý sẽ khác nhau.

Chẳng hạn, trong jQuery, tôi không muốn phải viết một trình xử lý lỗi duy nhất liên quan đến cả hai thứ như 500 và một số lỗi ngữ nghĩa dành riêng cho ứng dụng. Các khung khác, Ember cho một, cũng coi các lỗi HTTP như 400 và 500 giống hệt như các lỗi lớn, yêu cầu lập trình viên phát hiện những gì đang xảy ra và phân nhánh tùy thuộc vào việc đó có phải là lỗi "thực" hay không.


4
+1, P trong HTTP là viết tắt của Giao thức và nếu phản hồi là lỗi HTTP, thì đó sẽ là một vấn đề cấp thấp. Tôi đã tránh được rất nhiều sự phức tạp về mã trong những năm qua bằng cách sử dụng phương pháp được mô tả bởi torazaburo. Sẽ có ít đau đớn hơn trong vùng đất REST nếu tất cả chúng ta đã viết mã kiên cường thay vì thường xuyên bị lỗi HTTP.
Dem Pilafian

25
200 có nghĩa là yêu cầu đã được xử lý, do đó logic thành công thông thường sẽ được thực thi trên máy khách. Ở đây chúng tôi chắc chắn có lỗi, vì vậy phản hồi không thể có mã 2xx hoặc 3xx. Không thể là 5xx vì đó là lỗi phía máy chủ và chúng tôi có lỗi ở phía máy khách. Vì vậy, đó phải là một lỗi 4xx. Nhưng mô tả lỗi trong phần thân phản hồi là một điều đúng đắn và thực sự là một cách được thông số kỹ thuật HTTP khuyên dùng.
Alexey Guseynov

422 là tốt hơn, cho logger, proxy và các công cụ khác
Erik Aronesty

16

Sử dụng 400mã trạng thái cho bất kỳ mục đích nào khác ngoài việc chỉ ra rằng yêu cầu không đúng định dạng là hoàn toàn sai.

Nếu tải trọng yêu cầu chứa một chuỗi byte không thể được phân tích cú pháp dưới dạng application/json(nếu máy chủ mong đợi dạng dữ liệu đó), mã trạng thái thích hợp là 415:

Máy chủ đang từ chối phục vụ yêu cầu vì thực thể của yêu cầu ở định dạng không được hỗ trợ bởi tài nguyên được yêu cầu cho phương thức được yêu cầu.

Nếu tải trọng yêu cầu đúng về mặt cú pháp nhưng không chính xác về mặt ngữ nghĩa, 422mã phản hồi không chuẩn có thể được sử dụng hoặc 403mã trạng thái tiêu chuẩn :

Máy chủ hiểu yêu cầu, nhưng từ chối thực hiện nó. Ủy quyền sẽ không giúp đỡ và yêu cầu KHÔNG NÊN lặp lại.


3
không, 415 là khi thực thể được tuyên bố là sai loại, ví dụ image/gifthay vì text/json trong Content-Type:tiêu đề. - có lẽ điều này cũng được áp dụng nếu một thành phần của một nhiều phần dữ liệu có kiểu sai quy định, xem tools.ietf.org/html/rfc4918 nơi nó thảo luận về 422 để thảo luận nhiều hơn,
Jasen

8

Hãy suy nghĩ về những kỳ vọng.

Là một ứng dụng khách, bạn sẽ biết nếu có sự cố xảy ra ở phía máy chủ. Nếu máy chủ cần đưa ra lỗi khi blahthiếu hoặc requestedResourcegiá trị không chính xác thì lỗi 400 sẽ phù hợp.


5

Ngoài ra, đối với những người có thể gặp vấn đề tương tự như tôi, tôi đang sử dụng $.ajaxđể đăng dữ liệu biểu mẫu lên máy chủ và lúc đầu tôi cũng gặp 400lỗi.

Giả sử tôi có một biến javascript,

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

Không sử dụng biến formDatatrực tiếp làm giá trị của khóa datanhư dưới đây:

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

Thay vào đó, hãy sử dụng JSON.opesify để đóng gói formDatanhư dưới đây:

$.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); 
    }
});

Dù sao, như những người khác đã minh họa, lỗi là do máy chủ không thể nhận ra yêu cầu gây ra cú pháp không đúng, tôi chỉ đưa ra một ví dụ trong thực tế. Hy vọng nó sẽ hữu ích cho ai đó.


4

Trước tiên hãy kiểm tra URL có thể sai, nếu đúng thì hãy kiểm tra nội dung yêu cầu mà bạn đang gửi, nguyên nhân có thể là yêu cầu bạn đang gửi bị thiếu cú ​​pháp đúng.

Để giải thích, hãy kiểm tra các ký tự đặc biệt trong chuỗi yêu cầu. Nếu nó (char đặc biệt) đang được sử dụng thì đây là nguyên nhân gốc của lỗi này.

hãy thử sao chép yêu cầu và phân tích dữ liệu từng thẻ.


Tôi đã nhận được lỗi http 400, tôi đã kiểm tra yêu cầu của tôi có một số ký tự đặc biệt. Để khắc phục điều đó, tôi đã chuyển ký tự = UTF-8 trong loại nội dung.
Kislay Kishore
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.