400 BAD запит коду помилки HTTP, що означає?


346

У мене є запит JSON, який я публікую на HTTP-адресу.

Чи слід це трактувати як те, 400де requestedResourceіснує поле, але "Roman"це недійсне значення для цього поля?

[{requestedResource:"Roman"}] 

Чи слід це трактувати як те, 400де "blah"поле взагалі не існує?

[{blah:"Roman"}]

34
Можливо, 402 , якщо вони дійсно хочуть мати можливість відправити цінність Roman, їм потрібно просто заплатити більше :)
Jason Sperske

Реальний сценарій, коли я це бачив - я здійснив дзвінок PUT, щоб додати деякі дані. Я знову здійснив виклик put, використовуючи той самий орган запиту, і отримав 400, який сказав мені, що попередній запит вже обробляється. Це нормально для нашої системи, щоб додати ці дані.
MasterJoe2

Відповіді:


361

400 означає, що запит був неправильним. Іншими словами, потік даних, який клієнт відправляє на сервер, не відповідав правилам.

Що стосується API REST з корисним навантаженням JSON, 400-ти зазвичай, і я б правильно сказала, використовуються для вказівки на те, що JSON якимось чином недійсний відповідно до специфікації API для послуги.

За цією логікою обидва запропоновані вами сценарії повинні становити 400.

Уявіть, натомість це були XML, а не JSON. В обох випадках XML ніколи не пройде перевірку схеми - або через невизначений елемент, або через неправильне значення елемента. Це було б поганим проханням. Тут же угода.


3
Я погоджуюсь з вами до "За цією логікою, обидва запропоновані вами сценарії повинні становити 400". Я не думаю, що зміст JSON тут має значення. Коли ви скажете неправильно, я хотів би вважати, що вирішує проблеми у форматі надісланих вами даних, наприклад, якщо ви пропустите поле в JSON, ви повинні отримати 400.
Geethanga

2
Існує гідний набір кодів відповідей REST на сайті restapitutorial.com/httpstatuscodes.html . Це також може залежати від того, як ви хочете обробити дійсний запит, такий як метод 406 (неприйнятний) або 405 не дозволений. Однак 400 доцільно, оскільки "сервер не міг зрозуміти запит через неправильний синтаксис. Клієнт НЕ повинен повторювати запит без змін".
Ендрю Скотт Еванс

3
Отже, "запит не міг зрозуміти сервер через неправильно сформований синтаксис", це може бути або запит (наприклад, один із заголовків HTTP, який неправильно формується), або дані, передані запитом (наприклад, значення JSON відсутнє) ?
MC імператор

2
Відя каже, що "XML ніколи не пройде перевірку схеми". Справа в тому, що XML-аналізатори розрізняють добре сформований документ (тобто синтаксично звуковий) та дійсний (тобто семантично звуковий, наприклад, за схемою). Опис коду 400 - "запит не міг зрозуміти сервер через неправильний синтаксис " - тому його не слід використовувати для помилок перевірки, imho.
Мартін Лже

@Vidya stackoverflow.com/questions/42851301 / ... поглянути на цю помилку я також стикається той же питання , схожий на цю помилку , якщо ви знаєте , будь ласка , допоможіть мені
Mohan Gopi

74

Від w3.org

10.4.1 400 Поганий запит

Сервер не міг зрозуміти запит через неправильний синтаксис. Клієнт НЕ повинен повторювати запит без змін.


10
Правильність повернення помилки 400 базується не на полі проти значення, а на запиті в цілому. Я думаю, що HTTP 400 - це хороший шлях
Джейсон Сперський

Ви маєте на увазі, що відповідь 400 використовується для того, щоб сказати клієнтам, що що-небудь, наприклад URL-адреса, заголовки, тіло тощо, у запиті може бути неправильним, а не лише тілом?
MasterJoe2

3
добре для URL правильний код 404, для заголовків, я думаю, це підкидання, 403 (заборонено) здається правильним шляхом, якщо заголовки відкидають ідентичність, але що робити, якщо заголовки визначають вихідний формат? про єдиний шлях, на який я вважаю себе правильним для 400, - це ситуація, коли вимагається дія, яка не має сенсу і не повинна повторюватися. Я писав цю відповідь 4 роки тому, в ці дні я відчуваю, що навіть помилки повинні повернути 200, і що помилки повинні стосуватися лише передачі http, а не корисного навантаження.
Jason Sperske

1
Ця відповідь охоплює багато цього, хоча я не прочитав всі чарти ще stackoverflow.com/a/34324179/16959
Джейсон Sperske

@JasonSperske балансири навантажень, проксі-сервери та інші проміжні програми часто використовують коди статусу, щоб допомогти прокладати, звітувати та ремонтувати. на щастя, коди типу "422" прямо відносяться до корисного навантаження, тому в специфікації є місце для кодів статусу корисної навантаження.
Ерік Аронесті

53

Вибір коду відповіді HTTP є досить легким завданням і може бути описаний простими правилами. Єдина хитра частина, яку часто забувають, - параграф 6.5 від RFC 7231:

За винятком випадків, коли відповідаючи на запит HEAD, сервер ДОЛЖНІ надіслати представлення, що містить пояснення ситуації з помилками, і чи є це тимчасовою чи постійною умовою.

Правила такі:

  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 400 є недоцільним. Замість цього було б доречно повернути 200 разом з якимось об'єктом помилок, таким як { "error": { "message": "Unknown request keyword" } }чи будь-який інший.

Розглянемо шляхи обробки клієнта. Помилка в синтаксисі (наприклад, недійсний JSON) - це помилка в логіці програми, іншими словами помилка якоїсь форми, і з нею слід поводитися відповідно, схожим на 403, скажімо; іншими словами, щось погане пішло не так.

Помилка у значенні параметра, з іншого боку, є помилкою семантики, можливо, через неправильно підтверджений ввід користувача. Це не помилка HTTP (хоча, мабуть, це може бути 422). Шлях обробки був би іншим.

Наприклад, у jQuery я вважаю за краще не писати жодного обробника помилок, який стосується як речей, таких як 500, так і певних семантичних помилок, що стосуються додатків. Інші рамки, Ember for one, також трактують помилки HTTP, такі як 400s і 500s, однаково як великі збої в жирі, вимагаючи від програміста виявити, що відбувається і розгалужувати залежно від того, чи є "справжньою" помилкою чи ні.


4
+1, P у HTTP означає Протокол, і якщо відповідь є помилкою HTTP, це має бути проблемою низького рівня. Я уникав багатьох складних кодів протягом багатьох років, використовуючи підхід, описаний torazaburo. У землі REST було б менше больових відчуттів, якби ми всі писали стійкий код замість того, щоб так часто підірвати помилки HTTP.
Dem Pilafian

25
200 означає, що запит було оброблено, тому нормальна логіка успіху повинна бути виконана на клієнті. Тут ми точно маємо помилку, тому відповідь не може мати 2xx або 3xx код. Це не може бути 5xx, тому що це помилка на сервері, і у нас є помилка на стороні клієнта. Отже, це повинна бути помилка 4xx. Але опис помилки в тілі відповідей - це правильно зробити, і насправді це спосіб, який радить специфікація HTTP.
Олексій Гусейнов

422 краще, для лісорубів, проксі та інших інструментів
Ерік Аронесті

16

Використання 400кодів статусу для будь-якої іншої мети, ніж вказівка ​​на те, що запит є неправильним, просто помилково.

Якщо корисне навантаження запиту містить послідовність байтів, яку неможливо було проаналізувати як application/json(якщо сервер очікує, що цей формат даних), відповідний код статусу 415:

Сервер відмовляється обслуговувати запит, оскільки суть запиту знаходиться у форматі, не підтримуваному запитуваним ресурсом для запитуваного методу.

Якщо корисне навантаження запиту синтаксично правильне, але семантично неправильне, 422може бути використаний нестандартний код відповіді або стандартний 403код стану:

Сервер зрозумів запит, але відмовляється його виконувати. Авторизація не допоможе, і запит НЕ повинен повторюватися.


3
немає, 415 для коли особа , як стверджується, неправильного типу , наприклад , image/gifзамість того , щоб text/json в Content-Type:заголовку. - імовірно, це також застосовується, якщо компонент багаточастинки вказаний неправильний тип, див. tools.ietf.org/html/rfc4918, де він обговорює 422 для більшого обговорення,
Jasen

8

Подумайте про очікування.

Як клієнтський додаток, ви очікуєте знати, чи щось піде не так на стороні сервера. Якщо серверу потрібно видалити помилку, коли blahвона відсутня або requestedResourceзначення невірне, помилка 400 буде доречною.


5

Як доповнення, для тих, хто може зіткнутися з тією ж проблемою, що і моя, я використовую $.ajaxдля розміщення даних форми на сервері, і я також 400спочатку отримав помилку.

Припустимо, у мене змінна javascript,

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

У будь-якому випадку, як показали інші, помилка полягає в тому, що сервер не міг розпізнати запит, викликаючи неправильний синтаксис, я просто піднімаю екземпляр на практиці. Сподіваюся, комусь це буде корисно.


4

Спочатку перевірте URL-адресу, що вона може бути неправильною, якщо вона правильна, то перевірте те, що ви надсилаєте, орган запиту, який ви надсилаєте, можлива причина - запит про те, що ви надсилаєте, відсутній правильний синтаксис.

Щоб уточнити, перевірте наявність спеціальних символів у рядку запиту. Якщо він використовується (спеціальний знак), це першопричина цієї помилки.

спробуйте скопіювати запит і проаналізувати дані кожного тегу.


Я отримував помилку http 400, я перевіряв, чи є у мого запиту деякі спеціальні символи. Щоб виправити це, я передав charset = UTF-8 у тип вмісту.
Кіслай Кішор
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.