web-dev-qa-db-fra.com

400 BAD demande HTTP code d'erreur signifiant?

J'ai une demande JSON que je publie sur une URL HTTP.

Devrait-il être traité comme _400_ où requestedResource champ existe mais où _"Roman"_ est une valeur non valide pour ce champ?

_[{requestedResource:"Roman"}] 
_

Doit-il être traité comme un _400_ où le champ _"blah"_ n'existe pas du tout?

_[{blah:"Roman"}]
_
328
Phoenix

Un 400 signifie que la demande a été mal formée. En d'autres termes, le flux de données envoyé par le client au serveur ne respectait pas les règles.

Dans le cas d'une API REST avec une charge JSON, 400 sont généralement utilisés, et je dirais correctement, pour indiquer que le JSON est invalide d'une manière ou d'une autre conformément à la spécification d'API du service.

Selon cette logique, les deux scénarios que vous avez fournis devraient être 400.

Imaginez plutôt qu'il s'agisse de XML plutôt que de JSON. Dans les deux cas, le code XML ne passerait jamais la validation du schéma - en raison d'un élément indéfini ou d'une valeur d'élément incorrecte. Ce serait une mauvaise demande. Même affaire ici.

343
Vidya

De w3.org

10.4.1 400 mauvaise demande

La requête n'a pas pu être comprise par le serveur en raison d'une syntaxe mal formée. Le client NE DEVRAIT PAS répéter la demande sans modifications.

70
Jason Sperske

La sélection d'un code de réponse HTTP est une tâche assez facile et peut être décrite par de simples règles. La seule partie délicate qui est souvent oubliée est le paragraphe 6.5 de la RFC 7231:

Sauf en cas de réponse à une demande HEAD, le serveur DEVRAIT envoyer une représentation contenant une explication de la situation d'erreur et préciser s'il s'agit d'une condition temporaire ou permanente.

Les règles sont les suivantes:

  1. Si la requête aboutit, renvoyez le code 2xx (3xx pour la redirection). S'il y a eu une erreur de logique interne sur un serveur, retournez 5xx. Si quelque chose ne va pas dans la demande du client, retournez le code 4xx.
  2. Recherchez le code de réponse disponible dans la catégorie sélectionnée. Si l’un d’eux a un nom qui correspond bien à votre situation, vous pouvez l’utiliser. Sinon, il suffit de revenir au code x00 (200, 400, 500). Si vous en doutez, utilisez le code x00.
  3. Renvoie la description de l'erreur dans le corps de la réponse. Pour les codes 4xx, il doit contenir suffisamment d’informations pour permettre au développeur client de comprendre le motif et de réparer le client. Pour 5xx pour des raisons de sécurité, aucun détail ne doit être révélé.
  4. Si le client doit distinguer différentes erreurs et avoir une réaction différente en fonction de celle-ci, définissez un format d'erreur lisible par une machine et extensible, et utilisez-le partout dans votre API. C'est une bonne pratique de faire cela depuis le tout début.
  5. N'oubliez pas que le développeur du client peut faire des choses étranges et essayer d'analyser les chaînes que vous renvoyez en tant que description lisible par l'homme. Et en changeant les chaînes, vous casserez des clients si mal écrits. Par conséquent, fournissez toujours une description lisible par machine et évitez de signaler des informations supplémentaires sous forme de texte.

Donc, dans votre cas, j'avais renvoyé une erreur 400 et quelque chose comme ceci si "Roman" est obtenu à partir d'une entrée utilisateur et que le client doit avoir une réaction spécifique:

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

ou une erreur plus générique, si cette situation est une erreur de logique incorrecte chez un client et n'est pas attendue, sauf si le développeur a commis une erreur:

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

Dans les deux cas, la "syntaxe est mal formée". C'est la sémantique qui ne va pas. Par conséquent, IMHO a 400 est inapproprié. Au lieu de cela, il serait approprié de renvoyer un 200 avec une sorte d’objet d’erreur tel que { "error": { "message": "Unknown request keyword" } } ou autre.

Examinez le ou les chemins de traitement du client. Une erreur de syntaxe (par exemple, JSON invalide) est une erreur de la logique du programme, en d’autres termes, un bogue quelconque, et doit être traitée en conséquence, d’une manière similaire à un 403, par exemple; En d'autres termes, quelque chose de mauvais a mal tourné.

Une erreur dans une valeur de paramètre, en revanche, est une erreur de sémantique, peut-être due à une entrée utilisateur mal validée. Ce n'est pas une erreur HTTP (bien que je suppose que ce pourrait être un 422). Le chemin de traitement serait différent.

Par exemple, dans jQuery, je préférerais ne pas avoir à écrire un seul gestionnaire d’erreurs traitant à la fois des erreurs telles que 500 et des erreurs sémantiques spécifiques à une application. Les autres frameworks, Ember pour un, traitent également les erreurs HTTP 400 et 500 de manière identique, en demandant au programmeur de détecter ce qui se passe et de créer une branche, qu’il s’agisse d’une erreur "réelle" ou non.

20
user663031

L'utilisation de 400 codes de statut à des fins autres que d'indiquer que la requête est mal formée est tout simplement fausse.

Si la charge utile de la demande contient une séquence d'octets qui ne peut pas être analysée comme application/json (si le serveur attend ce format de données), le code d'état approprié est 415:

Le serveur refuse de traiter la demande car l'entité de la demande est dans un format non pris en charge par la ressource demandée pour la méthode demandée.

Si les données utiles de la demande sont syntaxiquement correctes mais sémantiquement incorrectes, le code de réponse non standard 422 peut être utilisé, ou le code d'état standard 403:

Le serveur a compris la demande, mais refuse de l'exécuter. L'autorisation n'aidera pas et la demande NE DEVRAIT PAS être répétée.

12
Cochise Ruhulessin

Pensez aux attentes.

En tant qu'application client, vous vous attendez à savoir si quelque chose ne va pas du côté du serveur. Si le serveur doit émettre une erreur lorsque blah est manquant ou si la valeur requestedResource est incorrecte, une erreur 400 conviendrait.

7
film42

Commencez par vérifier l'URL. Si elle est correcte, vérifiez le corps de la demande que vous envoyez. La cause possible est que la requête que vous envoyez manque de syntaxe correcte.

Pour élaborer, recherchez les caractères spéciaux dans la chaîne de requête. S'il est utilisé (caractère spécial), c'est la cause première de cette erreur.

essayez de copier la demande et analysez chaque donnée de balise.

3
Ankur Bhutani

En complément, pour ceux qui rencontrent le même problème que le mien, j’utilise $.ajax pour publier les données de formulaire sur le serveur et j’ai également eu l’erreur 400 au début.

Supposons que j'ai une variable javascript,

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

N'utilisez pas la variable formData directement comme valeur de la clé data comme ci-dessous:

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

À la place, utilisez JSON.stringify pour encapsuler le formData comme ci-dessous:

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

Quoi qu'il en soit, comme d'autres l'ont illustré, l'erreur provient du fait que le serveur n'a pas pu reconnaître la syntaxe malformée de la requête. Je soulève simplement une instance à la pratique. J'espère que cela serait utile à quelqu'un.

1
Gearon