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.