400 BAD meminta makna kode kesalahan HTTP?

346

Saya memiliki permintaan JSON yang saya posting ke URL HTTP.

Hal ini harus diperlakukan sebagai 400mana requestedResourcelapangan ada tapi "Roman"adalah nilai yang tidak valid untuk bidang ini?

[{requestedResource:"Roman"}] 

Hal ini harus diperlakukan sebagai 400mana "blah"lapangan tidak ada sama sekali?

[{blah:"Roman"}]
Phoenix
sumber
34
Mungkin 402 , jika mereka benar-benar ingin dapat mengirim nilainya Roman, mereka hanya perlu membayar lebih untuk Anda :)
Jason Sperske
Skenario nyata di mana saya melihat ini - saya melakukan panggilan PUT untuk menambahkan beberapa data. Saya melakukan panggilan lagi menggunakan badan permintaan yang sama dan mendapat 400 yang memberi tahu saya bahwa permintaan sebelumnya sedang diproses. Itu normal bagi sistem kami untuk mengambil beberapa waktu untuk menambahkan data itu.
MasterJoe2

Jawaban:

361

A 400 berarti bahwa permintaan salah. Dengan kata lain, aliran data yang dikirim oleh klien ke server tidak mengikuti aturan.

Dalam kasus REST API dengan payload JSON, 400's biasanya, dan dengan benar saya katakan, digunakan untuk menunjukkan bahwa JSON tidak valid dalam beberapa cara sesuai dengan spesifikasi API untuk layanan.

Dengan logika itu, kedua skenario yang Anda berikan harus 400-an.

Bayangkan saja ini XML dan bukan JSON. Dalam kedua kasus, XML tidak akan pernah melewati validasi skema - baik karena elemen yang tidak terdefinisi atau nilai elemen yang tidak tepat. Itu akan menjadi permintaan yang buruk. Kesepakatan yang sama di sini.

Vidya
sumber
3
Saya setuju dengan Anda hingga "Dengan logika itu, kedua skenario yang Anda sediakan harus berusia 400-an." Saya rasa konten JSON tidak penting di sini. Ketika Anda mengatakan cacat, saya ingin percaya bahwa mengatasi masalah dalam format data yang Anda kirim, misalnya jika Anda melewatkan bidang di JSON, Anda akan mendapatkan 400.
Geethanga
2
Ada serangkaian kode respons REST yang layak di restapitutorial.com/httpstatuscodes.html . Ini juga tergantung pada bagaimana Anda ingin menangani permintaan yang valid seperti metode 406 (Tidak Dapat Diterima) atau 405 yang tidak diizinkan. Namun, 400 sesuai karena "Permintaan tidak dapat dipahami oleh server karena sintaksis cacat. Klien TIDAK HARUS mengulangi permintaan tanpa modifikasi."
Andrew Scott Evans
3
Jadi "Permintaan tidak dapat dipahami oleh server karena sintaksis salah bentuk" dapat berupa salah satu permintaan (misalnya, salah satu tajuk HTTP rusak) atau data yang dibawa oleh permintaan (misalnya, nilai JSON hilang) ?
MC Kaisar
2
Vidya mengatakan "XML tidak akan pernah lulus validasi skema". Poinnya adalah bahwa parser XML membedakan antara dokumen yang dibentuk dengan baik (yaitu suara sintaksis) dan valid (yaitu suara semantik, misalnya sesuai dengan skema). Deskripsi kode 400 adalah "permintaan tidak dapat dipahami oleh server karena sintaksis cacat " - jadi itu tidak boleh digunakan untuk kesalahan validasi, imho.
Martin Lie
@Vidya stackoverflow.com/questions/42851301/… lihat kesalahan ini saya juga menghadapi masalah yang sama dengan kesalahan ini jika Anda tahu tolong bantu saya
Mohan Gopi
74

Dari w3.org

10.4.1 400 Permintaan Buruk

Permintaan tidak dapat dipahami oleh server karena sintaksis yang salah. Klien TIDAK HARUS mengulangi permintaan tanpa modifikasi.

Jason Sperske
sumber
10
Kebenaran mengembalikan kesalahan 400 tidak didasarkan pada bidang vs nilai tetapi permintaan secara keseluruhan. Saya pikir HTTP 400 adalah cara yang baik untuk pergi
Jason Sperske
Apakah maksud Anda bahwa respons 400 digunakan untuk memberi tahu klien bahwa ada sesuatu, yaitu url, tajuk, badan, dll., Dalam permintaan itu bisa salah dan bukan hanya badan?
MasterJoe2
3
baik untuk url kode yang benar adalah 404, untuk header, saya kira itu adalah melemparkan, 403 (dilarang) sepertinya cara yang tepat untuk pergi jika header menolak identitas, tetapi bagaimana jika header menentukan format output? tentang satu-satunya jalan yang saya rasa tepat untuk 400 adalah dalam situasi di mana tindakan diminta yang tidak masuk akal dan tidak boleh diulang. Saya menulis jawaban ini 4 tahun yang lalu, hari ini saya merasa bahkan kesalahan akan kembali 200, dan kesalahan hanya berlaku untuk transmisi http dan bukan pada muatan.
Jason Sperske
1
Jawaban ini mencakup banyak hal, meskipun saya belum membaca semua grafik namun stackoverflow.com/a/34324179/16959
Jason Sperske
@JasonSperske penyeimbang muatan, proksi, dan middleware lainnya sering menggunakan kode status untuk membantu rute, melaporkan & memperbaiki. untungnya kode seperti "422" secara tegas berkenaan dengan payload, jadi ada beberapa ruang dalam spec untuk kode status payload.
Erik Aronesty
53

Memilih kode respons HTTP adalah tugas yang cukup mudah dan dapat dijelaskan dengan aturan sederhana. Satu-satunya bagian rumit yang sering dilupakan adalah paragraf 6.5 dari RFC 7231:

Kecuali ketika menanggapi permintaan HEAD, server HARUS mengirim representasi yang berisi penjelasan tentang situasi kesalahan, dan apakah itu kondisi sementara atau permanen.

Aturannya adalah sebagai berikut:

  1. Jika permintaan berhasil, kembalikan kode 2xx (3xx untuk redirect). Jika ada kesalahan logika internal pada server, lalu kembalikan 5xx. Jika ada yang salah dalam permintaan klien, maka kembalikan kode 4xx.
  2. Cari melalui kode respons yang tersedia dari kategori yang dipilih. Jika salah satu dari mereka memiliki nama yang cocok dengan situasi Anda, Anda dapat menggunakannya. Kalau tidak, hanya mundur ke kode x00 (200, 400, 500). Jika Anda ragu, mundur ke kode x00.
  3. Kembalikan deskripsi kesalahan di badan respons. Untuk kode 4xx harus berisi informasi yang cukup bagi pengembang klien untuk memahami alasannya dan memperbaiki klien. Untuk 5xx karena alasan keamanan, tidak ada rincian yang harus diungkapkan.
  4. Jika klien perlu membedakan kesalahan yang berbeda dan memiliki reaksi yang berbeda bergantung padanya, tentukan format kesalahan yang dapat dibaca dan dikembangkan mesin dan gunakan di mana-mana di API Anda. Merupakan praktik yang baik untuk melakukannya sejak awal.
  5. Perlu diingat bahwa pengembang klien dapat melakukan hal-hal aneh dan mencoba mengurai string yang Anda kembalikan sebagai deskripsi yang dapat dibaca manusia. Dan dengan mengubah string Anda akan menghancurkan klien yang ditulis dengan buruk. Jadi selalu sediakan deskripsi yang dapat dibaca mesin dan cobalah untuk tidak melaporkan informasi tambahan dalam teks.

Jadi dalam kasus Anda, saya akan mengembalikan 400 kesalahan dan sesuatu seperti ini jika "Roman" diperoleh dari input pengguna dan klien harus memiliki reaksi spesifik:

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

atau kesalahan yang lebih umum, jika situasi seperti itu adalah kesalahan logika yang buruk pada klien dan tidak diharapkan, kecuali pengembang membuat kesalahan:

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

Dalam kedua kasus tidak ada "sintaksis cacat". Semantik yang salah. Oleh karena itu, IMHO 400 tidak pantas. Sebagai gantinya, akan lebih tepat untuk mengembalikan 200 bersama dengan beberapa jenis objek kesalahan seperti { "error": { "message": "Unknown request keyword" } }atau apa pun.

Pertimbangkan jalur pemrosesan klien. Kesalahan dalam sintaksis (misalnya JSON tidak valid) adalah kesalahan dalam logika program, dengan kata lain bug dari beberapa jenis, dan harus ditangani sesuai, dengan cara yang mirip dengan 403, katakanlah; dengan kata lain, sesuatu yang buruk telah salah.

Kesalahan dalam nilai parameter, di sisi lain, adalah kesalahan semantik, mungkin karena mengatakan input pengguna yang divalidasi dengan buruk. Ini bukan kesalahan HTTP (meskipun saya kira itu bisa menjadi 422). Jalur pemrosesan akan berbeda.

Sebagai contoh, di jQuery, saya lebih suka tidak harus menulis penangan kesalahan tunggal yang berhubungan dengan kedua hal seperti 500 dan beberapa kesalahan semantik khusus aplikasi. Kerangka kerja lain, Ember for one, juga memperlakukan kesalahan HTTP seperti 400 dan 500 secara identik sebagai kegagalan besar, yang mengharuskan programmer untuk mendeteksi apa yang terjadi dan bercabang tergantung pada apakah itu kesalahan "nyata" atau tidak.


sumber
4
+1, P dalam HTTP adalah singkatan dari Protokol dan jika responsnya adalah kesalahan HTTP, seharusnya masalah tingkat rendah. Saya telah menghindari banyak kerumitan kode selama bertahun-tahun menggunakan pendekatan yang dijelaskan oleh torazaburo. Akan ada lebih sedikit rasa sakit di tanah REST jika kita semua menulis kode ulet alih-alih begitu sering meledak dengan kesalahan HTTP.
Dem Pilafian
25
200 berarti permintaan telah diproses, sehingga logika keberhasilan yang normal harus dijalankan pada klien. Di sini kami pasti memiliki kesalahan, jadi respons tidak dapat memiliki kode 2xx atau 3xx. Tidak boleh 5xx juga karena itu adalah kesalahan sisi server dan kami memiliki kesalahan di sisi klien. Jadi itu pasti kesalahan 4xx. Tetapi deskripsi kesalahan dalam badan respons adalah hal yang benar untuk dilakukan dan sebenarnya merupakan cara yang disarankan oleh spesifikasi HTTP.
Alexey Guseynov
422 lebih baik, untuk penebang, proksi, dan alat lainnya
Erik Aronesty
16

Menggunakan 400kode status untuk tujuan lain apa pun selain menunjukkan bahwa permintaan yang salah benar-benar salah.

Jika payload permintaan berisi urutan byte yang tidak dapat diuraikan sebagai application/json(jika server mengharapkan format data itu), kode status yang sesuai adalah 415:

Server menolak untuk melayani permintaan karena entitas permintaan dalam format yang tidak didukung oleh sumber daya yang diminta untuk metode yang diminta.

Jika payload permintaan secara sintaksis benar tetapi semantik salah, 422kode respons non-standar dapat digunakan, atau 403kode status standar :

Server mengerti permintaan itu, tetapi menolak untuk memenuhinya. Otorisasi tidak akan membantu dan permintaan TIDAK HARUS diulang.

Cochise Ruhulessin
sumber
3
tidak, 415 adalah untuk saat entitas diklaim memiliki tipe yang salah, misalnya, image/gifbukan text/json di Content-Type:header. - mungkin ini juga berlaku jika komponen multipart memiliki tipe yang salah ditentukan, lihat tools.ietf.org/html/rfc4918 di mana ia membahas 422 untuk diskusi lebih lanjut,
Jasen
8

Pikirkan tentang harapan.

Sebagai aplikasi klien, Anda berharap tahu jika ada masalah di sisi server. Jika server perlu melakukan kesalahan saat blahhilang atau requestedResourcenilainya salah dari kesalahan 400 akan sesuai.

film42
sumber
5

Sebagai pelengkap, bagi mereka yang mungkin memenuhi masalah yang sama dengan saya, saya menggunakan $.ajaxuntuk mengirim data formulir ke server dan saya juga mendapat 400kesalahan pada awalnya.

Asumsikan saya memiliki variabel javascript,

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

Jangan gunakan variabel formDatasecara langsung sebagai nilai kunci dataseperti di bawah ini:

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

Sebaliknya, gunakan JSON.stringify untuk merangkum formDataseperti di bawah ini:

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

Lagi pula, seperti yang telah diilustrasikan orang lain, kesalahannya adalah karena server tidak dapat mengenali permintaan yang menyebabkan sintaksis salah bentuk, saya hanya memunculkan contoh saat latihan. Semoga bermanfaat bagi seseorang.

Eugene
sumber
4

Pertama periksa URL itu mungkin salah, jika sudah benar maka periksa badan permintaan yang Anda kirim, kemungkinan penyebabnya adalah permintaan yang Anda kirim tidak ada sintaks benar.

Untuk menguraikan, periksa karakter khusus dalam string permintaan. Jika itu (char khusus) sedang digunakan ini adalah akar penyebab kesalahan ini.

coba salin permintaan dan analisis masing-masing dan setiap data tag.

Ankur Bhutani
sumber
Saya mendapatkan kesalahan http 400, saya memeriksa permintaan saya memiliki beberapa karakter khusus. Untuk memperbaikinya, saya melewati charset = UTF-8 dalam tipe konten.
Kislay Kishore