Getirme özelliğini kullanarak çok parçalı form verileriyle nasıl POST yapabilirim?


90

Bunun gibi bir URL alıyorum:

fetch(url, {
  mode: 'no-cors',
  method: method || null,
  headers: {
    'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
    'Content-Type': 'multipart/form-data'
  },
  body: JSON.stringify(data) || null,
}).then(function(response) {
  console.log(response.status)
  console.log("response");
  console.log(response)
})

API'm verilerin olmasını bekliyor, multipart/form-databu yüzden content-typebu türden kullanıyorum ... Ama bana 400 durum kodu ile bir yanıt veriyor.

Kodumun nesi var?

Yanıtlar:


176

Sen kuruyorsun Content-Typeolmak multipart/form-data, ama sonra kullanarak JSON.stringifyhangi döner vücut verilere application/json. İçerik türü uyuşmazlığınız var.

Bunun multipart/form-datayerine verilerinizi kodlamanız gerekecek json. Genellikle multipart/form-datadosyaları yüklerken kullanılır ve bundan biraz daha karmaşıktır application/x-www-form-urlencoded(HTML formları için varsayılandır).

İçin şartname multipart/form-databulunabilir RFC 1867 .

Bu tür verilerin javascript aracılığıyla nasıl gönderileceği konusunda bir kılavuz için buraya bakın .

Temel fikir, FormData nesnesini kullanmaktır (IE <10'da desteklenmez):

async function sendData(url, data) {
  const formData  = new FormData();

  for(const name in data) {
    formData.append(name, data[name]);
  }

  const response = await fetch(url, {
    method: 'POST',
    body: formData
  });

  // ...
}

Başına bu makale marka emin değil ayarlamak için Content-Typebaşlık. Tarayıcı, boundaryparametre dahil, sizin için ayarlayacaktır .


const fd = new FormData (); // Yüklenecek dosya. fd.append ('dosya', fileToUpload); fd.append ('jsondatakey', 'jsondatavalue'); Bununla birlikte, vücuttaki bazı json verileriyle birlikte dosya gönderebileceksiniz.
— Jnana

Bir Yetkilendirmeye ihtiyacım olursa ne olur?
— DAVE

26

Geçenlerde IPFS ile çalışıyordum ve bunu çözdüm. IPFS'nin bir dosya yüklemesi için bir curl örneği şuna benzer:

curl -i -H "Content-Type: multipart/form-data; boundary=CUSTOM" -d $'--CUSTOM\r\nContent-Type: multipart/octet-stream\r\nContent-Disposition: file; filename="test"\r\n\r\nHello World!\n--CUSTOM--' "http://localhost:5001/api/v0/add"

Temel fikir, her bölüm (içinde dize tarafından bölünmüş olmasıdır boundaryile --), bu kendi başlıklarını sahiptir ( Content-Typeörneğin, ikinci bölümde.) FormDataBizim hedefleri gerçekleştirmek için daha iyi bir yolu yani nesne, sizin için tüm bu yönetir.

Bu, API'yi şu şekilde getirmek anlamına gelir:

const formData = new FormData()
formData.append('blob', new Blob(['Hello World!\n']), 'test')

fetch('http://localhost:5001/api/v0/add', {
  method: 'POST',
  body: formData
})
.then(r => r.json())
.then(data => {
  console.log(data)
})

17
Yukarıdaki yönteme dikkat edin, FormData'yı kullanarak yaparsanız üstbilgileri SAĞLAMAYIN çünkü otomatik olarak ayarlanan sınırı geçersiz kılar.
— Matt Pengelly

1
Teşekkürler @MattPengelly! Yetkilendirme gibi özel başlıklar nasıl ayarlanır?
— Dragos Strugar

7
@DragosStrugar hala üstbilgileri ayarlayabilirsiniz (Yetkilendirme dahil), FormData kullanıyorsanız Content-Type başlığını manuel olarak ayarlamayın.
— RobertMcReed

3
FormData kullanılıyorsa, 'Content-Type' başlıklarını SAĞLAMAYIN.
— caot

1
Curl örneğinde buna ihtiyacınız var. Örnekte FormDatabuna ihtiyacınız yoktur, çünkü tarayıcı bu başlığı sizin için gönderir ve aynı zamanda bu çözümün amacı olan tüm mime sınırlarını da yönetir.
— konsumer
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.