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

346

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

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

[{requestedResource:"Roman"}] 

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

[{blah:"Roman"}]
Феникс
источник
34
Может быть, 402 , если они действительно хотят иметь возможность отправить значение Roman, им просто нужно заплатить вам больше :)
Джейсон Сперске
Реальный сценарий, где я видел это - я сделал PUT-вызов, чтобы добавить некоторые данные. Я снова сделал вызов пут, используя то же тело запроса, и получил 400, который сказал мне, что предыдущий запрос уже обрабатывается. Это нормально для нашей системы, чтобы добавить эти данные.
MasterJoe2

Ответы:

361

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

В случае REST API с полезной нагрузкой 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 Emperor
2
Видья говорит, что «XML никогда не пройдет проверку схемы». Дело в том, что синтаксические анализаторы XML различают документ, который хорошо сформирован (т. Е. Синтаксически обоснован) и действителен (т. Е. Семантически обоснован, например, согласно схеме). Описание кода 400: «сервер не может понять запрос из-за неправильного синтаксиса », поэтому его не следует использовать для ошибок проверки, imho.
Мартин Ли
@Vidya stackoverflow.com/questions/42851301/… посмотрите на эту ошибку, я также сталкиваюсь с той же проблемой, похожей на эту ошибку, если вы знаете, пожалуйста, помогите мне
Мохан Гопи
74

С w3.org

10.4.1 400 неправильных запросов

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

Джейсон Сперске
источник
10
Правильность возврата ошибки 400 основана не на поле против значения, а на запросе в целом. Я думаю, что HTTP 400 - хороший путь
Джейсон Сперске
Вы имеете в виду, что ответ 400 используется для того, чтобы сообщить клиентам, что что-либо, например, URL, заголовки, тело и т. Д., В запросе может быть неправильным, а не только тело?
MasterJoe2
3
Что ж, для URL правильный код - 404, для заголовков, я полагаю, это ошибка, 403 (запрещено) кажется правильным путем, если заголовки отклоняют идентичность, но что, если заголовки определяют выходной формат? Единственный путь, который я считаю правильным для 400, - это ситуация, когда запрашивается действие, которое не имеет смысла и не должно повторяться. Я написал этот ответ 4 года назад, в настоящее время я чувствую, что даже ошибки должны возвращать 200, и что ошибки должны относиться только к передаче http, а не к полезной нагрузке.
Джейсон Сперске
1
Этот ответ покрывает многое из этого, хотя я еще не прочитал все графики stackoverflow.com/a/34324179/16959
Джейсон Сперске
Балансировщики нагрузки, прокси-серверы @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

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

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

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

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


источник
4
+1, P в HTTP обозначает Протокол и, если ответ является ошибкой HTTP, это должно быть проблемой низкого уровня. За эти годы я избежал большого количества сложностей кода, используя подход, описанный torazaburo. На земле REST было бы меньше боли, если бы мы все писали устойчивый код вместо того, чтобы часто взрываться с ошибками HTTP.
Дем Пилафян
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.

film42
источник
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); 
    }
});

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

Евгений
источник
Я думаю, что OP спрашивает, является ли 400 верным кодом ошибки для возврата , когда запрос не искажен, но каким-то образом не соответствует требованиям уровня приложения. Например, вы можете создать онлайн-калькулятор, в котором вы будете отправлять уравнения в виде JSON. Если вы отправляете действительный json с добавлением числа со строкой, тогда запрос верен, но семантически неверен для приложения. Однако ваш браузер увидит запрос как «плохой».
Jeppe
4

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

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

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

Анкур Бутани
источник
Я получаю ошибку http 400, я проверил, что в моем запросе есть специальные символы. Чтобы исправить это, я передал charset = UTF-8 в типе контента.
Кислай Кишор