400 KÖTÜ istek HTTP hata kodu anlamı?


346

Bir HTTP URL'sine yayınladığım bir JSON isteğim var.

Bu şekilde ele alınacak 400yerlerde requestedResourcetarla var ama "Roman"bu alan için geçersiz bir değer nedir?

[{requestedResource:"Roman"}] 

Bu şekilde ele alınacak 400nereye "blah"alan hiç biri yok?

[{blah:"Roman"}]

34
Belki 402 , gerçekten değeri gönderebilmek Romanistiyorlarsa, size daha fazla ödeme yapmaları gerekiyor :)
Jason Sperske

Bunu gördüğüm gerçek bir senaryo - bazı veriler eklemek için bir PUT çağrısı yaptım. Aynı istek gövdesini kullanarak tekrar arama yaptım ve önceki bir isteğin zaten işlendiğini söyleyen 400'ü aldım. Sistemimizin bu verileri eklemek için biraz zaman alması normaldir.
MasterJoe2

Yanıtlar:


361

400, isteğin hatalı biçimlendirildiği anlamına gelir. Başka bir deyişle, istemci tarafından sunucuya gönderilen veri akışı kurallara uymadı.

Bir JSON yükü olan bir REST API durumunda, 400's tipik ve doğru söyleyebilirim, JSON hizmet için API belirtimine göre bir şekilde geçersiz olduğunu belirtmek için kullanılır.

Bu mantıkla, sağladığınız her iki senaryo da 400 olmalıdır.

Bunun yerine bunun JSON yerine XML olduğunu düşünün. Her iki durumda da XML, tanımsız bir öğe veya yanlış bir öğe değeri nedeniyle hiçbir zaman şema doğrulamasından geçmez. Bu kötü bir istek olurdu. Aynı anlaşma burada.


3
"Bu mantıkla, sağladığınız her iki senaryo da 400 olmalıdır." JSON içeriğinin burada önemli olduğunu düşünmüyorum. Yanlış biçimlendirdiğinizde, gönderdiğiniz veriler biçimindeki sorunları
çözdüğüne inanmak isterim

2
Restapitutorial.com/httpstatuscodes.html adresinde iyi bir REST yanıt kodu kümesi vardır . Ayrıca, 406 (Kabul Edilemez) veya 405 yöntemine izin verilmiyor gibi geçerli bir isteği nasıl işlemek istediğinize bağlı olabilir. Ancak 400, "İstek hatalı biçimlendirilmiş sözdizimi nedeniyle anlaşılamadı. İstemci, değişiklik yapmadan isteği yinelememelidir."
Andrew Scott Evans

3
Bu nedenle "İstek, bozuk biçimli sözdizimine sunucu tarafından anlaşılacaktır olabilir" ya olabilir isteğe (örneğin, bir HTTP başlıkları bozuk biçimli olmak üzere) ya da veri talebi tarafından taşınan (örneğin, bir JSON değeri eksik) ?
MC İmparatoru

2
Vidya "XML asla şema doğrulamasını geçmeyecek" diyor. XML ayrıştırıcılarının iyi biçimlendirilmiş (yani sözdizimsel olarak sağlam) ve geçerli (yani anlamsal olarak sağlam olan, örneğin bir şemaya göre) bir belge arasında ayrım yaptığı nokta. 400 kodunun açıklaması "istek, hatalı biçimlendirilmiş sözdizimi nedeniyle sunucu tarafından anlaşılamadı " - bu nedenle doğrulama hataları için kullanılmamalıdır, imho.
Martin Lie

@Vidya stackoverflow.com/questions/42851301/… bu hatayı bir göz atın ben de bu hatayı benzer aynı sorunla karşı karşıya biliyorsanız lütfen bana yardım edin
Mohan Gopi

74

Gönderen w3.org

10.4.1 400 Hatalı İstek

İstek, hatalı biçimlendirilmiş sözdizimi nedeniyle sunucu tarafından anlaşılamadı. İstemci, değişiklik yapmadan isteği tekrarlamamalıdır.


10
400 hatası döndürmenin doğruluğu, bir alana karşılık bir değere değil, bir bütün olarak isteğe bağlıdır. HTTP 400'ün gitmek için iyi bir yol olduğunu düşünüyorum
Jason Sperske

Müşterilere, istekte url, üstbilgiler, gövde vb. Herhangi bir şeyin yalnızca gövde değil, yanlış olabileceğini söylemek için 400 yanıtın kullanılması mı demek istiyorsunuz?
MasterJoe2

3
iyi url için doğru kod 404, başlıklar için, sanırım bu bir atma, 403 (yasak) başlıklar kimlik reddediyorsa, gitmek için doğru yol gibi görünüyor, ama üstbilgiler çıktı biçimini belirlerse ne olacak? 400 için doğru olduğunu düşündüğüm tek yol hakkında, mantıklı olmayan ve tekrarlanmaması gereken bir eylemin talep edildiği durumda. Bu cevabı 4 yıl önce yazdım, bu günlerde hatalar bile 200'ü döndürmeli ve hataların yük için değil, yalnızca http iletimine uygulanması gerektiğini hissediyorum.
Jason Sperske

1
Tüm cevapları henüz okumadım, ancak bu cevap çok şey
içeriyor,

@ JasonSperske yük dengeleyicileri, proxy'ler ve diğer ara katman yazılımları genellikle rota, rapor ve onarım için durum kodlarını kullanır. neyse ki "422" gibi kodlar açıkça yük ile ilgilidir, bu nedenle yükte durum kodları için spesifikasyonda yer vardır.
Erik Aronesty

53

Bir HTTP yanıt kodu seçmek oldukça kolay bir iştir ve basit kurallarla açıklanabilir. Sıklıkla unutulan tek zor kısım RFC 7231'den 6.5 numaralı paragraftır:

Bir HEAD isteğine yanıt verirken, sunucu, hata durumunun açıklamasını ve geçici veya kalıcı bir durum olup olmadığını içeren bir temsil göndermelidir.

Kurallar aşağıdaki gibidir:

  1. İstek başarılı olursa, 2xx kodunu döndürün (yönlendirme için 3xx). Bir sunucuda dahili bir mantık hatası varsa, 5xx değerini döndürün. İstemci isteğinde yanlış bir şey varsa, 4xx kodunu döndürün.
  2. Seçili kategorideki kullanılabilir yanıt kodunu inceleyin. Bunlardan birinin durumunuzla iyi eşleşen bir adı varsa, bunu kullanabilirsiniz. Aksi takdirde sadece x00 koduna (200, 400, 500) geri dönün. Şüpheniz varsa, x00 koduna geri dönün.
  3. Yanıt gövdesinde hata açıklaması döndür. 4xx kodları için, istemci geliştiricinin nedeni anlaması ve istemciyi düzeltmesi için yeterli bilgi içermesi gerekir. Güvenlik nedeniyle 5xx için hiçbir ayrıntı açıklanmamalıdır.
  4. İstemcinin farklı hataları ayırt etmesi ve buna bağlı olarak farklı tepki göstermesi gerekiyorsa, makine tarafından okunabilir ve genişletilebilir bir hata biçimi tanımlayın ve API'nizin her yerinde kullanın. Bunu en baştan yapmak iyi bir uygulamadır.
  5. İstemci geliştiricinin garip şeyler yapabileceğini ve insan tarafından okunabilir açıklama olarak döndürdüğünüz dizeleri ayrıştırmaya çalışabileceğini unutmayın. Ve dizeleri değiştirerek böyle kötü yazılmış istemcileri kıracaksınız. Bu nedenle her zaman makinede okunabilir açıklama sağlayın ve metinde ek bilgi bildirmekten kaçının.

Yani sizin durumda 400 hata ve kullanıcı girişinden "Roman" elde edilir ve istemci belirli bir tepki olması gerekiyorsa böyle bir şey döndürdü:

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

veya bu tür bir durum istemcide kötü bir mantık hatasıysa ve geliştirici yanlış bir şey yapmadığı sürece beklenmiyorsa, daha genel bir hata:

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

21

Her iki durumda da "sözdizimi hatalı biçimlendirilmiş" değildir. Yanlış anlambilimdir. Bu nedenle, IMHO a 400 uygun değildir. Bunun yerine, 200 gibi bir tür hata nesnesiyle birlikte { "error": { "message": "Unknown request keyword" } }veya başka bir şey döndürmek uygun olacaktır .

İstemci işleme yollarını düşünün. Sözdizimindeki bir hata (örn. Geçersiz JSON), programın mantığındaki bir hatadır, başka bir deyişle bir çeşit hatadır ve buna göre, 403'e benzer bir şekilde ele alınmalıdır; diğer bir deyişle, kötü bir şey ters gitti.

Bir parametre değerindeki bir hata, diğer bir deyişle, belki de zayıf doğrulanmış kullanıcı girişi nedeniyle semantik bir hatadır. Bir HTTP hatası değil (her ne kadar bir 422 olabilir varsayalım). İşleme yolu farklı olacaktır.

Örneğin, jQuery'de, 500 ve bazı uygulamaya özgü semantik hatalar ile ilgilenen tek bir hata işleyicisi yazmak zorunda kalmamayı tercih ederim. Ember, diğeri için 400'lü ve 500'lü HTTP hatalarını büyük yağ hataları olarak aynı şekilde ele alır ve programcının "gerçek" bir hata olup olmadığına bağlı olarak neler olup bittiğini saptamasını gerektirir.


4
+1, HTTP'deki P , Protokol anlamına gelir ve yanıt bir HTTP hatasıysa, düşük düzeyli bir sorun olmalıdır. Torazaburo tarafından açıklanan yaklaşımı kullanarak yıllar boyunca çok fazla kod karmaşıklığından kaçındım. Hepimiz HTTP hatalarıyla sık sık patlamak yerine esnek kod yazsaydık REST ülkesinde daha az acı olur .
Dem Pilafian

25
200, isteğin işlendiği anlamına gelir, bu nedenle istemcide normal bir başarı mantığı yürütülmelidir. Burada kesinlikle bir hata var, bu nedenle yanıtın 2xx veya 3xx kodu olamaz. Bu 5xx olamaz çünkü bu bir sunucu tarafı hatası ve istemci tarafında bir hata var. Bu bir 4xx hatası olmalıdır. Ancak yanıt gövdesindeki hata açıklaması yapmak için doğru bir şeydir ve aslında HTTP belirtimi tarafından önerilen bir yoldur.
Alexey Guseynov

Kaydediciler, vekiller ve diğer araçlar için 422 daha iyidir
Erik Aronesty

16

Kullanılması 400belirten dışında başka bir amaçla durum kodları isteği hatalı olup sadece düz yanlış.

İstek yükü, ayrıştırılamayan bir bayt dizisi içeriyorsa application/json(sunucu bu veri biçimini beklerse), uygun durum kodu 415:

İsteğin varlığı, istenen yöntem için istenen kaynak tarafından desteklenmeyen bir biçimde olduğundan sunucu istekte bulunmayı reddediyor.

İstek yükü sözdizimsel olarak doğru ancak anlamsal olarak yanlışsa, standart olmayan 422yanıt kodu veya standart 403durum kodu kullanılabilir:

Sunucu isteği anladı, ancak yerine getirmeyi reddediyor. Yetkilendirme yardımcı olmaz ve istek tekrarlanmamalıdır.


3
hayır, 415 varlık türü yanlış eg olduğu iddia edildiğinde içindir image/gifyerine text/json de Content-Type:başlığındaki. - muhtemelen bu, çok parçalı bir bileşenin yanlış türde belirtilmiş olması durumunda da geçerlidir, daha fazla tartışma için 422 tartışıldığı tools.ietf.org/html/rfc4918 adresine bakın ,
Jasen

8

Beklentileri düşünün.

Bir istemci uygulaması olarak, sunucu tarafında bir sorun olup olmadığını bilmeyi beklersiniz. Sunucunun blaheksik olduğunda bir hata atması gerekiyorsa veya requestedResourcedeğer 400 hatadan yanlışsa uygun olur.


5

Tamamlayıcı olarak, benimkiyle aynı sorunu karşılayabilenler için, $.ajaxform verilerini sunucuya göndermek için kullanıyorum 400ve ilk başta hatayı aldım .

Javascript değişkenim olduğunu varsayalım,

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

Değişkeni formDatadoğrudan anahtarın değeri olarak dataaşağıdaki gibi kullanmayı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); 
    }
});

Bunun yerine, formDataaşağıdaki gibi kapsüllemek için JSON.stringify kullanın :

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

Her neyse, diğerlerinin de gösterdiği gibi, hata, sunucunun hatalı biçimlendirilmiş sözdizimine neden olan isteği tanıyamaması nedeniyle, sadece pratikte bir örnek yükseltiyorum. Umarım birisi için yararlı olur.


Bence istek hatalı, ancak bir şekilde uygulama düzeyinde gereksinimleri karşılamadığında, 400, dönmek için uygun hata kodu olup olmadığını soruyor düşünüyorum . Örneğin, denklemleri JSON olarak gönderdiğiniz çevrimiçi bir hesap makinesi oluşturabilirsiniz. Dize ile bir sayı eklemek için geçerli bir json gönderirseniz, istek doğrudur, ancak uygulama için anlamsal olarak yanlıştır. Ancak tarayıcınız isteği 'kötü' olarak görecektir.
Jeppe

4

Öncelikle URL'nin yanlış olabileceğini kontrol edin, doğruysa, daha sonra gönderdiğiniz istek gövdesini kontrol edin, olası neden, gönderdiğiniz isteğin doğru sözdizimi eksik olmasıdır.

Ayrıntılı olarak, istek dizesinde özel karakterler olup olmadığını kontrol edin. (Özel karakter) kullanılıyorsa, bu hatanın temel nedeni budur.

isteği kopyalamayı deneyin ve her bir etiket verisini analiz edin.


Http 400 hatası alıyordum, isteğimin bazı özel karakterleri olduğunu kontrol ettim. Bunu düzeltmek için içerik türünde charset = UTF-8'i geçtim.
Kislay Kishore
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.