400 BAD request HTTP error code meaning?

346

Eu tenho uma solicitação JSON que estou postando em um URL HTTP.

Isso deve ser tratado como o campo 400onde requestedResourceexiste, mas "Roman"é um valor inválido para esse campo?

[{requestedResource:"Roman"}] 

Isso deve ser tratado como 400onde o "blah"campo não existe?

[{blah:"Roman"}]
Fénix
fonte
34
Talvez 402 , se eles realmente querem ser capaz de enviar o valor Roman, eles só precisam de pagar mais :)
Jason Sperske
Um cenário real em que vi isso - fiz uma chamada PUT para adicionar alguns dados. Fiz uma chamada novamente com o mesmo corpo da solicitação e recebi uma 400 que me disse que uma solicitação anterior já está sendo processada. É normal que o nosso sistema leve algum tempo para adicionar esses dados.
MasterJoe2

Respostas:

361

Um 400 significa que a solicitação foi malformada. Em outras palavras, o fluxo de dados enviado pelo cliente ao servidor não seguiu as regras.

No caso de uma API REST com uma carga JSON, 400 é normalmente, e eu diria corretamente, usado para indicar que o JSON é inválido de alguma forma, de acordo com a especificação da API para o serviço.

Por essa lógica, os dois cenários que você forneceu devem ter 400.

Imagine, em vez disso, que eram XML e não JSON. Nos dois casos, o XML nunca passaria na validação de esquema - devido a um elemento indefinido ou a um valor inadequado do elemento. Isso seria um pedido ruim. O mesmo negócio aqui.

Vidya
fonte
3
Eu concordo com você até "Por essa lógica, os dois cenários que você forneceu devem ter 400". Não acho que o conteúdo do JSON deva importar aqui. Quando você diz mal formado Eu gostaria de acreditar que aborda as questões no formato dos dados que você enviar, por exemplo, se você pular um campo no JSON você deve obter 400.
Geethanga
2
Há um conjunto decente de códigos de resposta REST em restapitutorial.com/httpstatuscodes.html . Também pode depender de como você deseja lidar com uma solicitação válida, como um método 406 (Não Aceitável) ou 405, não permitido. No entanto, 400 é apropriado porque "A solicitação não pôde ser entendida pelo servidor devido à sintaxe malformada. O cliente NÃO DEVE repetir a solicitação sem modificações."
Andrew Scott Evans
3
Portanto, "A solicitação não pôde ser entendida pelo servidor devido à sintaxe malformada" pode ser a solicitação (por exemplo, um dos cabeçalhos HTTP está malformado) ou os dados transportados pela solicitação (por exemplo, um valor JSON ausente) ?
MC Emperor
2
Vidya diz que "o XML nunca passaria na validação de esquema". Aponte que os analisadores XML distinguem entre um documento que está sendo bem formado (ou seja, sintaticamente correto) e válido (ou seja, semanticamente correto, por exemplo, de acordo com um esquema). A descrição do código 400 é "a solicitação não pôde ser entendida pelo servidor devido à sintaxe malformada " - portanto, não deve ser usada para erros de validação.
27630 Martin Lie
@Vidya stackoverflow.com/questions/42851301/... dar uma olhada este erro eu também estou enfrentando mesmo problema semelhante a esse erro se você sabe ajuda por favor me
Mohan Gopi
74

De w3.org

10.4.1 400 Solicitação incorreta

A solicitação não pôde ser entendida pelo servidor devido à sintaxe incorreta. O cliente não deve repetir o pedido sem modificações.

Jason Sperske
fonte
10
A correção de retornar um erro 400 não se baseia em um campo versus um valor, mas na solicitação como um todo. Acho HTTP 400 é um bom caminho a percorrer
Jason Sperske
Você quer dizer que uma resposta 400 seja usada para informar aos clientes que qualquer coisa, por exemplo, URL, cabeçalhos, corpo etc., na solicitação pode estar errada e não apenas o corpo?
MasterJoe2
3
bem, para o URL, o código correto é 404, para os cabeçalhos, acho que é um lance para cima, 403 (proibido) parece o caminho certo a seguir se os cabeçalhos estiverem rejeitando a identidade, mas e se os cabeçalhos estiverem determinando o formato de saída? o único caminho que acho adequado para 400 está na situação em que uma ação está sendo solicitada que não faz sentido e não deve ser repetida. Escrevi essa resposta há 4 anos. Hoje em dia, sinto que mesmo os erros devem retornar 200 e que esses erros devem se aplicar apenas à transmissão http e não à carga útil.
Jason Sperske
11
Esta resposta abrange um monte de presente, embora eu não tenha lido através de todas as cartas ainda stackoverflow.com/a/34324179/16959
Jason Sperske
Os balanceadores de carga, proxies e outros middlewares do @JasonSperske geralmente usam códigos de status para ajudar a direcionar, reportar e reparar. felizmente, códigos como "422" são expressamente relacionados à carga útil; portanto, há espaço nas especificações para códigos de status de carga útil.
Erik Aronesty 29/05/19
53

A seleção de um código de resposta HTTP é uma tarefa bastante fácil e pode ser descrita por regras simples. A única parte complicada que é frequentemente esquecida é o parágrafo 6.5 da RFC 7231:

Exceto ao responder a uma solicitação HEAD, o servidor DEVE enviar uma representação contendo uma explicação da situação de erro e se é uma condição temporária ou permanente.

As regras são as seguintes:

  1. Se a solicitação for bem-sucedida, retorne o código 2xx (3xx para redirecionamento). Se houve um erro lógico interno em um servidor, retorne 5xx. Se houver algo errado na solicitação do cliente, retorne o código 4xx.
  2. Veja o código de resposta disponível da categoria selecionada. Se um deles tiver um nome que corresponda bem à sua situação, você poderá usá-lo. Caso contrário, faça o fallback para o código x00 (200, 400, 500). Se você duvida, use o código x00.
  3. Retorne a descrição do erro no corpo da resposta. Para códigos 4xx, ele deve conter informações suficientes para que o desenvolvedor do cliente entenda o motivo e corrija o cliente. Para 5xx por motivos de segurança, nenhum detalhe deve ser revelado.
  4. Se o cliente precisar distinguir erros diferentes e ter uma reação diferente dependendo dele, defina um formato de erro legível e extensível por máquina e use-o em qualquer lugar em sua API. É uma boa prática fazer isso desde o início.
  5. Lembre-se de que o desenvolvedor do cliente pode fazer coisas estranhas e tentar analisar as strings que você retorna como descrição legível por humanos. E alterando as strings, você quebrará esses clientes mal escritos. Portanto, sempre forneça uma descrição legível por máquina e tente evitar informações adicionais em texto.

Portanto, no seu caso, retornei um erro 400 e algo assim se "Roman" for obtido da entrada do usuário e o cliente tiver uma reação específica:

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

ou um erro mais genérico, se essa situação for um erro lógico ruim em um cliente e não for esperado, a menos que o desenvolvedor tenha feito algo errado:

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

Em nenhum dos casos a "sintaxe está malformada". É a semântica que está errada. Portanto, IMHO a 400 é inadequado. Em vez disso, seria apropriado retornar um 200 junto com algum tipo de objeto de erro como { "error": { "message": "Unknown request keyword" } }ou o que seja.

Considere o (s) caminho (s) de processamento do cliente. Um erro na sintaxe (por exemplo, JSON inválido) é um erro na lógica do programa, ou seja, é algum tipo de bug e deve ser tratado de acordo, de maneira semelhante a 403, por exemplo; em outras palavras, algo de errado deu errado.

Um erro em um valor de parâmetro, por outro lado, é um erro de semântica, talvez devido a dizer entrada de usuário mal validada. Não é um erro HTTP (embora eu suponha que possa ser um 422). O caminho do processamento seria diferente.

Por exemplo, no jQuery, eu preferiria não precisar escrever um único manipulador de erros que lide com coisas como 500 e algum erro semântico específico do aplicativo. Outras estruturas, o Ember, por exemplo, também tratam erros HTTP como 400 e 500 idênticos como grandes falhas de gordura, exigindo que o programador detecte o que está acontecendo e se ramifique, dependendo se é um erro "real" ou não.


fonte
4
+1, OP no HTTP significa Protocolo e, se a resposta for um erro HTTP, deve ser um problema de baixo nível. Evitei muita complexidade de código ao longo dos anos usando a abordagem descrita por torazaburo. Haveria menos problemas na região REST se todos nós escrevêssemos código resiliente em vez de explodir com tanta freqüência com erros de HTTP.
Dem Pilafian
25
200 significa que a solicitação foi processada; portanto, uma lógica normal de sucesso deve ser executada em um cliente. Definitivamente, aqui temos um erro, portanto, a resposta não pode ter código 2xx ou 3xx. Também não pode ser 5xx porque esse é um erro no servidor e temos um erro no cliente. Portanto, esse deve ser um erro 4xx. Mas a descrição do erro no corpo da resposta é a coisa certa a ser feita e é realmente uma maneira recomendada pela especificação HTTP.
Alexey Guseynov
422 é melhor, por madeireiros, proxies e outras ferramentas
Erik Aronesty
16

O uso de 400códigos de status para qualquer outra finalidade que não seja a indicação de que a solicitação está incorreta está completamente errado.

Se a carga útil da solicitação contiver uma sequência de bytes que não pôde ser analisada como application/json(se o servidor espera esse formato de dados), o código de status apropriado é 415:

O servidor está se recusando a atender a solicitação porque a entidade da solicitação está em um formato não suportado pelo recurso solicitado para o método solicitado.

Se a carga útil da solicitação estiver sintaticamente correta, mas semanticamente incorreta, o 422código de resposta não padrão poderá ser usado ou o 403código de status padrão :

O servidor entendeu a solicitação, mas se recusa a atendê-la. A autorização não ajudará e a solicitação NÃO DEVE ser repetida.

Cochise Ruhulessin
fonte
3
não, 415 é para quando a entidade é reivindicada como sendo do tipo errado, por exemplo, em image/gifvez de text/json no Content-Type:cabeçalho. - presumivelmente, isso também é aplicável se um componente de uma peça múltipla tiver o tipo errado especificado, consulte tools.ietf.org/html/rfc4918, onde ele discute 422 para obter mais discussões.
Jasen
8

Pense nas expectativas.

Como um aplicativo cliente, você espera saber se algo der errado no lado do servidor. Se o servidor precisar gerar um erro quando blahestiver ausente ou se o requestedResourcevalor estiver incorreto, seria apropriado um erro 400.

film42
fonte
5

Como um complemento, para aqueles que podem encontrar o mesmo problema que o meu, estou usando $.ajaxpara postar dados do formulário no servidor e também obtive o 400erro no início.

Suponha que eu tenho uma variável javascript,

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

Não use a variável formDatadiretamente como o valor da chave datacomo abaixo:

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

Em vez disso, use JSON.stringify para encapsular o formDataseguinte:

$.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 qualquer forma, como outros ilustraram, o erro ocorre porque o servidor não pôde reconhecer a solicitação que causava sintaxe malformada; estou apenas levantando uma instância na prática. Espero que seja útil para alguém.

Eugene
fonte
4

Primeiro, verifique o URL, pois pode estar errado; se estiver correto, verifique o corpo da solicitação que você está enviando; a causa possível é a solicitação que você está enviando, faltando a sintaxe correta.

Para elaborar, verifique se há caracteres especiais na sequência de solicitação. Se estiver sendo usado (caractere especial), essa é a causa raiz desse erro.

tente copiar a solicitação e analisar todos os dados das tags.

Ankur Bhutani
fonte
Eu estava recebendo o erro http 400, verifiquei se minha solicitação tinha alguns caracteres especiais. Para corrigir isso, passei o charset = UTF-8 no tipo de conteúdo.
precisa saber é o seguinte