400 BAD Anfrage HTTP Fehlercode Bedeutung?

346

Ich habe eine JSON-Anfrage, die ich an eine HTTP-URL sende.

Sollte dies so behandelt werden, als 400ob ein requestedResourceFeld vorhanden wäre, aber "Roman"ein ungültiger Wert für dieses Feld ist?

[{requestedResource:"Roman"}] 

Sollte dies so behandelt werden, als 400ob ein "blah"Feld überhaupt nicht existiert?

[{blah:"Roman"}]
Phönix
quelle
34
Vielleicht 402 , wenn sie wirklich in der Lage sein wollen, den Wert zu senden Roman, müssen sie Ihnen nur mehr bezahlen :)
Jason Sperske
Ein reales Szenario, in dem ich dies gesehen habe - ich habe einen PUT-Aufruf durchgeführt, um einige Daten hinzuzufügen. Ich habe erneut einen Put-Anruf mit demselben Anfragetext durchgeführt und eine 400 erhalten, die mir mitteilte, dass eine vorherige Anfrage bereits verarbeitet wird. Es ist normal, dass unser System einige Zeit benötigt, um diese Daten hinzuzufügen.
MasterJoe2

Antworten:

360

Ein 400 bedeutet, dass die Anforderung fehlerhaft war. Mit anderen Worten, der vom Client an den Server gesendete Datenstrom entsprach nicht den Regeln.

Im Fall einer REST-API mit einer JSON-Nutzlast werden normalerweise 400 verwendet, und ich würde zu Recht sagen, dass der JSON gemäß der API-Spezifikation für den Dienst in irgendeiner Weise ungültig ist.

Nach dieser Logik sollten beide von Ihnen bereitgestellten Szenarien 400 sein.

Stellen Sie sich stattdessen vor, dies wäre eher XML als JSON. In beiden Fällen würde das XML niemals die Schemaüberprüfung bestehen - entweder aufgrund eines undefinierten Elements oder eines falschen Elementwerts. Das wäre eine schlechte Anfrage. Gleiches Angebot hier.

Vidya
quelle
3
Ich stimme Ihnen bis zu "Nach dieser Logik sollten beide von Ihnen bereitgestellten Szenarien 400 sein." Ich denke nicht, dass der Inhalt des JSON hier eine Rolle spielen sollte. Wenn Sie sagen, dass Sie fehlerhaft sind, würde ich gerne glauben, dass dies die Probleme im Format der von Ihnen
gesendeten Daten behebt.
2
Unter restapitutorial.com/httpstatuscodes.html gibt es einen anständigen Satz von REST- Antwortcodes . Dies kann auch davon abhängen, wie Sie eine gültige Anforderung behandeln möchten, z. B. eine 406-Methode (nicht akzeptabel) oder eine 405-Methode, die nicht zulässig ist. 400 ist jedoch angemessen, da "die Anforderung vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden konnte. Der Client sollte die Anforderung NICHT ohne Änderungen wiederholen."
Andrew Scott Evans
3
So „die Anforderung konnte nicht von dem Server aufgrund ungültiger Syntax zu verstehen“ kann entweder die seine Anforderung (zum Beispiel eine der HTTP - Header ist fehlerhaft) , oder die Daten von der Anforderung ausgeführt (beispielsweise ein JSON Wert fehlt) ?
MC Emperor
2
Vidya sagt, "das XML würde niemals die Schemaüberprüfung bestehen". Der Punkt ist, dass XML-Parser zwischen einem Dokument unterscheiden, das wohlgeformt (dh syntaktisch einwandfrei) und gültig (dh semantisch einwandfrei, z. B. nach einem Schema) ist. Die Beschreibung des 400-Codes lautet "Die Anforderung konnte vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden ". Sie sollte daher nicht für Validierungsfehler verwendet werden, imho.
Martin Lie
@Vidya stackoverflow.com/questions/42851301/… werfen Sie einen Blick auf diesen Fehler Ich bin auch mit dem gleichen Problem ähnlich wie dieser Fehler konfrontiert, wenn Sie wissen, bitte helfen Sie mir
Mohan Gopi
74

Von w3.org

10.4.1 400 Bad Request

Die Anforderung konnte vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden. Der Client sollte die Anfrage NICHT ohne Änderungen wiederholen.

Jason Sperske
quelle
10
Die Richtigkeit der Rückgabe eines Fehlers 400 basiert nicht auf einem Feld gegenüber einem Wert, sondern auf der Anforderung als Ganzes. Ich denke, HTTP 400 ist ein guter Weg zu gehen
Jason Sperske
Meinen Sie damit, dass eine 400-Antwort verwendet wird, um Kunden mitzuteilen, dass irgendetwas, dh URL, Header, Text usw. in der Anfrage, falsch sein könnte und nicht nur der Text?
MasterJoe2
3
Nun, für URL ist der richtige Code 404, für Header ist es wohl ein Fehler. 403 (verboten) scheint der richtige Weg zu sein, wenn Header die Identität ablehnen, aber was ist, wenn Header das Ausgabeformat bestimmen? Der einzige Weg, den ich für 400 für richtig halte, ist die Situation, in der eine Aktion angefordert wird, die keinen Sinn ergibt und nicht wiederholt werden sollte. Ich habe diese Antwort vor 4 Jahren geschrieben. Heutzutage denke ich, dass sogar Fehler 200 zurückgeben sollten und dass Fehler nur für die http-Übertragung und nicht für die Nutzlast gelten sollten.
Jason Sperske
1
Diese Antwort deckt eine Menge davon ab, obwohl ich noch nicht alle Diagramme durchgelesen
Jason Sperske
@JasonSperske Load Balancer, Proxys und andere Middleware verwenden häufig Statuscodes, um Routen, Berichte und Reparaturen zu unterstützen. Glücklicherweise beziehen sich Codes wie "422" ausdrücklich auf die Nutzlast, so dass in der Spezifikation etwas Platz für Nutzlaststatuscodes vorhanden ist.
Erik Aronesty
53

Die Auswahl eines HTTP-Antwortcodes ist eine recht einfache Aufgabe und kann durch einfache Regeln beschrieben werden. Der einzige schwierige Teil, der oft vergessen wird, ist Absatz 6.5 aus RFC 7231:

Außer bei der Beantwortung einer HEAD-Anfrage sollte der Server eine Darstellung senden, die eine Erläuterung der Fehlersituation enthält und angibt, ob es sich um eine vorübergehende oder eine dauerhafte Bedingung handelt.

Die Regeln lauten wie folgt:

  1. Wenn die Anforderung erfolgreich war, geben Sie 2xx-Code zurück (3xx für die Umleitung). Wenn auf einem Server ein interner Logikfehler aufgetreten ist, geben Sie 5xx zurück. Wenn in der Clientanforderung etwas nicht stimmt, geben Sie den 4xx-Code zurück.
  2. Durchsuchen Sie den verfügbaren Antwortcode aus der ausgewählten Kategorie. Wenn einer von ihnen einen Namen hat, der gut zu Ihrer Situation passt, können Sie ihn verwenden. Ansonsten einfach auf x00-Code (200, 400, 500) zurückgreifen. Wenn Sie Zweifel haben, greifen Sie auf x00-Code zurück.
  3. Fehlerbeschreibung im Antworttext zurückgeben. Für 4xx-Codes muss es genügend Informationen enthalten, damit der Cliententwickler den Grund versteht und den Client repariert. Aus Sicherheitsgründen müssen aus Sicherheitsgründen keine Details bekannt gegeben werden.
  4. Wenn der Client unterschiedliche Fehler unterscheiden und abhängig davon unterschiedlich reagieren muss, definieren Sie ein maschinenlesbares und erweiterbares Fehlerformat und verwenden Sie es überall in Ihrer API. Es ist eine gute Praxis, dies von Anfang an zu tun.
  5. Denken Sie daran, dass Client-Entwickler möglicherweise seltsame Dinge tun und versuchen, Zeichenfolgen zu analysieren, die Sie als lesbare Beschreibung zurückgeben. Und wenn Sie die Zeichenfolgen ändern, brechen Sie solche schlecht geschriebenen Clients. Geben Sie daher immer eine maschinenlesbare Beschreibung an und vermeiden Sie es, zusätzliche Informationen im Text zu melden.

In Ihrem Fall habe ich also 400 Fehler zurückgegeben und so etwas, wenn "Roman" aus Benutzereingaben erhalten wird und der Client eine bestimmte Reaktion haben muss:

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

oder ein allgemeinerer Fehler, wenn eine solche Situation ein fehlerhafter Logikfehler in einem Client ist und nicht erwartet wird, es sei denn, der Entwickler hat etwas falsch gemacht:

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

In keinem Fall ist die "Syntax fehlerhaft". Es ist die Semantik, die falsch ist. Daher ist meiner Meinung nach eine 400 unangemessen. Stattdessen wäre es angebracht, eine 200 zusammen mit einer Art Fehlerobjekt wie { "error": { "message": "Unknown request keyword" } }oder was auch immer zurückzugeben.

Betrachten Sie die Client-Verarbeitungspfade. Ein Fehler in der Syntax (z. B. ungültiger JSON) ist ein Fehler in der Logik des Programms, dh ein Fehler, und sollte entsprechend behandelt werden, ähnlich wie beispielsweise bei einem 403; Mit anderen Worten, etwas Schlimmes ist schiefgegangen.

Ein Fehler in einem Parameterwert ist andererseits ein Fehler der Semantik, möglicherweise aufgrund einer schlecht validierten Benutzereingabe. Es ist kein HTTP-Fehler (obwohl es vermutlich ein 422 sein könnte). Der Verarbeitungspfad wäre anders.

In jQuery würde ich es beispielsweise vorziehen, keinen einzigen Fehlerbehandler schreiben zu müssen, der sich sowohl mit 500 als auch mit einem app-spezifischen semantischen Fehler befasst. Andere Frameworks, zum Beispiel Ember, behandeln HTTP-Fehler wie 400er und 500er ebenfalls als große Fettfehler, sodass der Programmierer erkennen muss, was vor sich geht, und verzweigen muss, je nachdem, ob es sich um einen "echten" Fehler handelt oder nicht.


quelle
4
+1, Das P in HTTP steht für Protokoll. Wenn die Antwort ein HTTP-Fehler ist, sollte es sich um ein Problem auf niedriger Ebene handeln. Ich habe im Laufe der Jahre mit dem von torazaburo beschriebenen Ansatz viel Codekomplexität vermieden. Es würde weniger Schmerzen im REST-Land geben, wenn wir alle ausfallsicheren Code schreiben würden , anstatt so häufig mit HTTP-Fehlern in die Luft zu jagen.
Dem Pilafian
25
200 bedeutet, dass die Anforderung verarbeitet wurde, sodass eine normale Erfolgslogik auf einem Client ausgeführt werden sollte. Hier haben wir definitiv einen Fehler, daher kann die Antwort keinen 2xx- oder 3xx-Code haben. Es kann auch nicht 5xx sein, da dies ein serverseitiger Fehler ist und wir einen Fehler auf der Clientseite haben. Das muss also ein 4xx-Fehler sein. Die Fehlerbeschreibung im Antworttext ist jedoch richtig und wird von der HTTP-Spezifikation empfohlen.
Alexey Guseynov
422 ist besser, für Logger, Proxies und andere Tools
Erik Aronesty
16

Die Verwendung von 400Statuscodes für einen anderen Zweck als die Angabe, dass die Anforderung fehlerhaft ist, ist einfach falsch.

Wenn die Anforderungsnutzlast eine Bytefolge enthält, die nicht analysiert werden konnte application/json(wenn der Server dieses Datenformat erwartet), lautet der entsprechende Statuscode 415:

Der Server weigert sich, die Anforderung zu bearbeiten, da die Entität der Anforderung in einem Format vorliegt, das von der angeforderten Ressource für die angeforderte Methode nicht unterstützt wird.

Wenn die Anforderungsnutzlast syntaktisch korrekt, aber semantisch falsch ist, kann der nicht standardmäßige 422Antwortcode oder der Standardstatuscode 403verwendet werden:

Der Server hat die Anfrage verstanden, weigert sich jedoch, sie zu erfüllen. Die Autorisierung hilft nicht und die Anfrage sollte nicht wiederholt werden.

Cochise Ruhulessin
quelle
3
Nein, 415 ist für den Fall vorgesehen, dass die Entität vom falschen Typ ist, z. B. image/gifanstelle text/json der Content-Type:Kopfzeile. - Vermutlich gilt dies auch, wenn für eine Komponente eines Multiparts der falsche Typ angegeben ist. Weitere Informationen finden Sie unter tools.ietf.org/html/rfc4918.
Jasen
8

Denken Sie an Erwartungen.

Als Client-App erwarten Sie, dass Sie wissen, ob auf der Serverseite etwas schief geht. Wenn der Server einen Fehler auslösen muss, wenn er blahfehlt oder der requestedResourceWert falsch ist, ist ein Fehler von 400 angemessen.

film42
quelle
5

Als Ergänzung für diejenigen, die möglicherweise das gleiche Problem wie ich haben, verwende ich, $.ajaxum Formulardaten auf dem Server zu veröffentlichen, und ich habe auch die400 Fehler erhalten.

Angenommen, ich habe eine Javascript-Variable.

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

Verwenden Sie die Variable nicht formDatadirekt als Schlüsselwert datawie folgt:

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

Verwenden Sie stattdessen JSON.stringify, um Folgendes zu kapseln 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); 
    }
});

Wie andere bereits gezeigt haben, liegt der Fehler darin, dass der Server die Anfrage aufgrund einer fehlerhaften Syntax nicht erkennen konnte. Ich habe gerade eine Instanz in der Praxis ausgelöst. Hoffe es wäre hilfreich für jemanden.

Eugene
quelle
4

Überprüfen Sie zuerst die URL, die möglicherweise falsch ist. Wenn sie korrekt ist, überprüfen Sie dann den Anforderungshauptteil, den Sie senden. Die mögliche Ursache ist, dass die von Ihnen gesendete Anforderung die richtige Syntax fehlt.

Überprüfen Sie zum Ausarbeiten die Anforderungszeichenfolge auf Sonderzeichen. Wenn es (Sonderzeichen) verwendet wird, ist dies die Hauptursache für diesen Fehler.

Versuchen Sie, die Anforderung zu kopieren, und analysieren Sie alle Tag-Daten.

Ankur Bhutani
quelle
Ich habe einen http 400-Fehler erhalten und überprüft, ob meine Anfrage einige Sonderzeichen enthält. Um dies zu beheben, habe ich den Zeichensatz = UTF-8 im Inhaltstyp übergeben.
Kislay Kishore