400 BAD запрос Значение кода ошибки HTTP?

У меня есть запрос JSON, который я отправляю на URL-адрес HTTP.

Должно ли это рассматриваться как 400 где requestedResource поле существует, но "Roman" является недопустимым значением для этого поля?

[{requestedResource:"Roman"}] 

Должно ли это рассматриваться как 400, где поле "blah" вообще не существует?

[{blah:"Roman"}]

Ответ 1

A 400 означает, что запрос был искажен. Другими словами, поток данных, отправленный клиентом на сервер, не соответствовал правилам.

В случае REST API с полезной нагрузкой JSON 400 обычно и, как я бы сказал, используется, чтобы указать, что JSON некорректен в соответствии со спецификацией API для службы.

По этой логике оба сценария, которые вы предоставили, должны быть 400.

Представьте себе, что это скорее XML, чем JSON. В обоих случаях XML никогда не будет проходить проверку схемы - либо из-за элемента undefined, либо из-за неправильного значения элемента. Это будет плохая просьба. Та же сделка здесь.

Ответ 2

От w3.org

10.4.1 400 Плохой запрос

Запрос не мог быть понят сервером из-за неправильного синтаксис. Клиент НЕ ДОЛЖЕН повторять запрос без модификаций.

Ответ 3

Выбор кода ответа HTTP - довольно простая задача и может быть описана простыми правилами. Единственная сложная часть, которая часто забывается, - это параграф 6.5 из RFC 7231:

За исключением случаев ответа на запрос HEAD, сервер ДОЛЖЕН отправить представление, содержащее объяснение ситуации ошибки, и является ли это временным или постоянным условием.

Правила следующие:

  • Если запрос был успешным, верните код 2xx (3xx для перенаправления). Если на сервере возникла внутренняя логическая ошибка, верните 5xx. Если в запросе клиента есть что-то не так, верните код 4xx.
  • Просмотрите доступный код ответа из выбранной категории. Если у одного из них есть имя, которое хорошо соответствует вашей ситуации, вы можете его использовать. В противном случае просто отмените код x00 (200, 400, 500). Если вы сомневаетесь, откажитесь от кода x00.
  • Возвращает описание ошибки в теле ответа. Для кодов 4xx он должен содержать достаточно информации для разработчика клиента, чтобы понять причину и исправить клиента. Для 5xx из-за соображений безопасности подробности не должны раскрываться.
  • Если клиенту необходимо различать различные ошибки и в зависимости от него различная реакция, определите машинный читаемый и расширяемый формат ошибок и используйте его везде в вашем API. Это хорошая практика сделать это с самого начала.
  • Имейте в виду, что клиентский разработчик может делать странные вещи и пытаться проанализировать строки, которые вы возвращаете как удобное для чтения описание. И, изменив строки, вы сломаете таких плохо написанных клиентов. Поэтому всегда предоставляйте машиносчитываемое описание и старайтесь избегать сообщения дополнительной информации в тексте.

Итак, в вашем случае я вернул ошибку 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"
}

Ответ 4

В любом случае "синтаксис искажен". Это неверная семантика. Следовательно, ИМХО 400 не подходит. Вместо этого было бы целесообразно вернуть 200 вместе с каким-то объектом ошибки, таким как { "error": { "message": "Unknown request keyword" } } или что-то еще.

Рассмотрим путь обработки клиента. Ошибка в синтаксисе (например, недопустимый JSON) является ошибкой в ​​логике программы, другими словами, какой-то ошибкой, и ее следует обрабатывать соответствующим образом, аналогично 403; другими словами, что-то плохое пошло не так.

Ошибка в значении параметра, с другой стороны, является ошибкой семантики, возможно, из-за плохо подтвержденного ввода пользователем. Это не ошибка HTTP (хотя я полагаю, что это может быть 422). Путь обработки будет другим.

Например, в jQuery я бы предпочел не писать одиночный обработчик ошибок, который имеет дело с такими вещами, как 500 и некоторые семантические ошибки, специфичные для приложения. Другие фреймворки, Ember для одного, также обрабатывают ошибки HTTP, такие как 400 и 500, одинаково, как большие отказы жира, требуя от программиста обнаружить, что происходит и что происходит, в зависимости от того, является ли это "реальной" ошибкой или нет.

Ответ 5

Использование 400 кодов состояния для любых других целей, кроме указания того, что запрос искажен, просто неверно.

Если полезная нагрузка запроса содержит байтовую последовательность, которая не может быть проанализирована как application/json (если сервер ожидает эту форму данных), соответствующий код состояния 415:

Сервер отказывается обслуживать запрос, поскольку объект запрос находится в формате, не поддерживаемом запрошенным ресурсом для запрошенный метод.

Если полезная нагрузка запроса синтаксически корректна, но семантически некорректна, может использоваться нестандартный код ответа 422 или стандартный код состояния 403:

Сервер понял запрос, но отказывается его выполнять. Авторизация не поможет, и запрос НЕ ДОЛЖЕН повториться.

Ответ 6

Подумайте о ожиданиях.

Как клиентское приложение, вы ожидаете узнать, что что-то пошло не так на стороне сервера. Если серверу необходимо выбросить ошибку, если blah отсутствует или значение requestedResource неверно, чем ошибка 400.

Ответ 7

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

Чтобы разработать, проверьте специальные символы в строке запроса. Если используется (специальный char), это является основной причиной этой ошибки.

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

Ответ 8

В качестве дополнения, для тех, кто может столкнуться с той же проблемой, что и я, я использую $.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); 
    }
});

В любом случае, как показали другие, ошибка заключается в том, что сервер не может распознать запрос, так как синтаксис искажен, я просто привожу пример на практике. Надеюсь, это будет полезно для кого-то.