400 BAD solicitud de código de error HTTP significado?

346

Tengo una solicitud JSON que estoy publicando en una URL HTTP.

¿Debería tratarse esto como 400donde requestedResourceexiste el campo pero "Roman"es un valor no válido para este campo?

[{requestedResource:"Roman"}] 

¿Debería tratarse esto como 400donde el "blah"campo no existe en absoluto?

[{blah:"Roman"}]
Fénix
fuente
34
Tal vez 402 , si realmente quieren poder enviar el valor Roman, solo necesitan pagarle más :)
Jason Sperske
Un escenario real donde vi esto: hice una llamada PUT para agregar algunos datos. Hice una llamada de nuevo usando el mismo cuerpo de solicitud y obtuve un 400 que me decía que ya se estaba procesando una solicitud anterior. Es normal que nuestro sistema tarde un poco en agregar esos datos.
MasterJoe2

Respuestas:

361

Un 400 significa que la solicitud fue malformada. En otras palabras, el flujo de datos enviado por el cliente al servidor no siguió las reglas.

En el caso de una API REST con una carga útil JSON, los 400 son típicamente, y diría correctamente, que se utilizan para indicar que el JSON no es válido de alguna manera de acuerdo con la especificación API para el servicio.

Según esa lógica, los dos escenarios que proporcionó deben ser de 400.

Imagínese, en cambio, que fuera XML en lugar de JSON. En ambos casos, el XML nunca pasaría la validación del esquema, ya sea debido a un elemento indefinido o un valor de elemento incorrecto. Esa sería una mala solicitud. El mismo trato aquí.

Vidya
fuente
3
Estoy de acuerdo con usted hasta "Según esa lógica, los dos escenarios que proporcionó deben ser 400". No creo que el contenido de JSON deba importar aquí. Cuando diga malformado, me gustaría creer que aborda los problemas en el formato de los datos que envía, por ejemplo, si omite un campo en el JSON, debería obtener 400.
Geethanga
2
Hay un conjunto decente de códigos de respuesta REST en restapitutorial.com/httpstatuscodes.html . También puede depender de cómo desea manejar una solicitud válida, como un método 406 (no aceptable) o 405 no permitido. Sin embargo, 400 es apropiado porque "el servidor no pudo entender la solicitud debido a una sintaxis incorrecta. El cliente NO DEBE repetir la solicitud sin modificaciones".
Andrew Scott Evans
3
Por lo tanto, "El servidor no pudo entender la solicitud debido a una sintaxis con formato incorrecto" puede ser una solicitud (por ejemplo, uno de los encabezados HTTP que tiene un formato incorrecto) o los datos transportados por la solicitud (por ejemplo, falta un valor JSON) ?
MC Emperor
2
Vidya dice "el XML nunca pasaría la validación del esquema". Señale que los analizadores XML distinguen entre un documento bien formado (es decir, sintácticamente sólido) y válido (es decir, semánticamente sólido, por ejemplo, de acuerdo con un esquema). La descripción del código 400 es "el servidor no pudo entender la solicitud debido a una sintaxis con formato incorrecto ", por lo que no debería usarse para errores de validación, en mi humilde opinión.
Martin Lie
@Vidya stackoverflow.com/questions/42851301/… eche un vistazo a este error También estoy enfrentando el mismo problema similar a este error si sabe, por favor
ayúdenme
74

De w3.org

10.4.1 400 Solicitud incorrecta

El servidor no pudo entender la solicitud debido a una sintaxis incorrecta. El cliente NO DEBE repetir la solicitud sin modificaciones.

Jason Sperske
fuente
10
La exactitud de devolver un error 400 no se basa en un campo frente a un valor, sino en la solicitud en su conjunto. Creo que HTTP 400 es un buen camino
Jason Sperske
¿Quiere decir que se debe usar una respuesta 400 para decirles a los clientes que cualquier cosa, es decir, url, encabezados, cuerpo, etc., en la solicitud podría estar equivocada y no solo el cuerpo?
MasterJoe2
3
bueno para url, el código correcto es 404, para los encabezados, supongo que es un error, 403 (prohibido) parece ser el camino correcto si los encabezados rechazan la identidad, pero ¿qué pasa si los encabezados determinan el formato de salida? El único camino que creo que es correcto para 400 es en la situación en la que se solicita una acción que no tiene sentido y que no debe repetirse. Escribí esta respuesta hace 4 años, en estos días siento que incluso los errores deberían devolver 200, y que los errores solo deberían aplicarse a la transmisión http y no a la carga útil.
Jason Sperske el
1
Esta respuesta cubre mucho de esto, aunque todavía no he leído todos los cuadros stackoverflow.com/a/34324179/16959
Jason Sperske el
Los equilibradores de carga @JasonSperske, los servidores proxy y otros middleware a menudo usan códigos de estado para ayudar a enrutar, informar y reparar. afortunadamente, los códigos como "422" se refieren expresamente a la carga útil, por lo que hay espacio en la especificación para los códigos de estado de la carga útil.
Erik Aronesty
53

Seleccionar un código de respuesta HTTP es una tarea bastante fácil y puede describirse mediante reglas simples. La única parte difícil que a menudo se olvida es el párrafo 6.5 del RFC 7231:

Excepto cuando se responde a una solicitud HEAD, el servidor DEBE enviar una representación que contenga una explicación de la situación de error y si se trata de una condición temporal o permanente.

Las reglas son las siguientes:

  1. Si la solicitud fue exitosa, devuelva el código 2xx (3xx para la redirección). Si hubo un error lógico interno en un servidor, devuelva 5xx. Si hay algo incorrecto en la solicitud del cliente, devuelva el código 4xx.
  2. Mire el código de respuesta disponible de la categoría seleccionada. Si uno de ellos tiene un nombre que coincida bien con su situación, puede usarlo. De lo contrario, simplemente recurra al código x00 (200, 400, 500). Si tiene dudas, recurra al código x00.
  3. Descripción del error de retorno en el cuerpo de la respuesta. Para los códigos 4xx debe contener suficiente información para que el desarrollador del cliente comprenda el motivo y arregle el cliente. Para 5xx por razones de seguridad, no se deben revelar detalles.
  4. Si el cliente necesita distinguir diferentes errores y tener diferentes reacciones dependiendo de él, defina un formato de error legible por máquina y extensible y úselo en todas partes en su API. Es una buena práctica hacer eso desde el principio.
  5. Tenga en cuenta que el desarrollador del cliente puede hacer cosas extrañas e intentar analizar las cadenas que devuelve como descripción legible por humanos. Y al cambiar las cadenas, romperá clientes tan mal escritos. Por lo tanto, siempre proporcione una descripción legible por máquina e intente evitar informar información adicional en el texto.

Entonces, en su caso, devolví un error 400 y algo como esto si se obtiene "Roman" de la entrada del usuario y el cliente debe tener una reacción específica:

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

o un error más genérico, si dicha situación es un error lógico incorrecto en un cliente y no se espera, a menos que el desarrollador haya hecho algo incorrecto:

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

En ninguno de los casos la "sintaxis está mal formada". Son las semánticas las que están equivocadas. Por lo tanto, en mi humilde opinión un 400 es inapropiado. En cambio, sería apropiado devolver un 200 junto con algún tipo de objeto de error como { "error": { "message": "Unknown request keyword" } }o lo que sea.

Considere las rutas de procesamiento del cliente. Un error en la sintaxis (por ejemplo, JSON no válido) es un error en la lógica del programa, en otras palabras, un error de algún tipo, y debe manejarse en consecuencia, de manera similar a un 403, por ejemplo; en otras palabras, algo malo salió mal.

Un error en un valor de parámetro, por otro lado, es un error de semántica, tal vez debido a una entrada de usuario mal validada. No es un error HTTP (aunque supongo que podría ser un 422). La ruta de procesamiento sería diferente.

Por ejemplo, en jQuery, preferiría no tener que escribir un único controlador de errores que se ocupe de cosas como 500 y algún error semántico específico de la aplicación. Otros marcos, Ember para uno, también tratan los errores HTTP como los 400 y 500 de manera idéntica como grandes fallas gordas, lo que requiere que el programador detecte lo que está sucediendo y se ramifique dependiendo de si es un error "real" o no.


fuente
44
+1, La P en HTTP significa Protocolo y si la respuesta es un error HTTP, debería ser un problema de bajo nivel. He evitado una gran cantidad de complejidad de código a lo largo de los años utilizando el enfoque descrito por torazaburo. Habría menos dolor en la tierra REST si todos escribiéramos código resistente en lugar de explotar con tanta frecuencia con errores HTTP.
Dem Pilafian
25
200 significa que la solicitud se ha procesado, por lo que se debe ejecutar una lógica de éxito normal en un cliente. Aquí definitivamente tenemos un error, por lo que la respuesta no puede tener un código 2xx o 3xx. Tampoco puede ser 5xx porque es un error del lado del servidor y tenemos un error en el lado del cliente. Entonces eso debe ser un error 4xx. Pero la descripción del error en el cuerpo de la respuesta es lo correcto y en realidad es una forma recomendada por la especificación HTTP.
Alexey Guseynov
422 es mejor, para madereros, representantes y otras herramientas
Erik Aronesty
16

Usar 400códigos de estado para cualquier otro propósito que no sea indicar que la solicitud está mal formada es simplemente incorrecto.

Si la carga útil de la solicitud contiene una secuencia de bytes que no se pudo analizar como application/json(si el servidor espera ese formato de datos), el código de estado apropiado es 415:

El servidor se niega a atender la solicitud porque la entidad de la solicitud está en un formato no admitido por el recurso solicitado para el método solicitado.

Si la carga útil de la solicitud es sintácticamente correcta pero semánticamente incorrecta, 422se puede usar el código de respuesta no estándar o el 403código de estado estándar :

El servidor entendió la solicitud, pero se niega a cumplirla. La autorización no ayudará y la solicitud NO DEBE repetirse.

Cochise Ruhulessin
fuente
3
no, 415 es para cuando se afirma que la entidad es del tipo incorrecto, por ejemplo, en image/giflugar de text/json en el Content-Type:encabezado. - presumiblemente esto también es aplicable si un componente de una multiparte tiene el tipo incorrecto especificado, vea tools.ietf.org/html/rfc4918 donde se analiza 422 para más discusión,
Jasen
8

Piensa en las expectativas.

Como aplicación cliente, espera saber si algo sale mal en el lado del servidor. Si el servidor necesita arrojar un error cuando blahfalta o el requestedResourcevalor es incorrecto, sería apropiado un error 400.

film42
fuente
5

Como complemento, para aquellos que podrían tener el mismo problema que el mío, estoy usando $.ajaxpara publicar datos del formulario en el servidor y también recibí el 400error al principio.

Supongamos que tengo una variable de JavaScript,

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

No use la variable formDatadirectamente como el valor de la clave datacomo a continuación:

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

En su lugar, use JSON.stringify para encapsular lo formDatasiguiente:

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

De todos modos, como otros han ilustrado, el error se debe a que el servidor no pudo reconocer que la solicitud causaba una sintaxis incorrecta, solo estoy planteando una instancia en la práctica. Espero que sea útil para alguien.

Eugene
fuente
4

Primero verifique la URL, puede estar equivocada, si es correcta, luego verifique el cuerpo de la solicitud que está enviando, la posible causa es que la solicitud que está enviando no tiene la sintaxis correcta.

Para elaborar, verifique si hay caracteres especiales en la cadena de solicitud. Si se está utilizando (char especial), esta es la causa raíz de este error.

intente copiar la solicitud y analice todos y cada uno de los datos de etiquetas.

Ankur Bhutani
fuente
Estaba recibiendo un error http 400, verifiqué que mi solicitud tuviera algunos caracteres especiales. Para arreglar eso, pasé el charset = UTF-8 en el tipo de contenido.
Kislay Kishore