2016-02-04 15 views
24

Ich bin eine URL wie das Abrufen:holen Post mit mehrteiliger Formulardaten

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) 
}) 

Meine API die Daten so sein, von multipart/form-data erwartet ich content-type dieser Art bin mit ... Aber es gibt mir eine Antwort mit Statuscode 400.

Was ist falsch an meinem Code?

Antwort

44

Sie setzen die Content-Type auf multipart/form-data, aber verwenden Sie dann JSON.stringify auf die Körperdaten, die application/json zurückgibt. Sie haben einen Inhaltstyp, der nicht übereinstimmt.

Sie müssen Ihre Daten als multipart/form-data anstelle von json kodieren. Normalerweise wird multipart/form-data beim Hochladen von Dateien verwendet und ist etwas komplizierter als application/x-www-form-urlencoded (das ist der Standard für HTML-Formulare). Die Spezifikation für multipart/form-data finden Sie in RFC 1867.

Eine Anleitung zum Einreichen dieser Art von Daten über Javascript finden Sie unter here.

Die Grundidee ist es, die FormData Objekt zu verwenden (nicht in IE unterstützt < 10):

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

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

    fetch(url, { 
    method: 'POST', 
    body: formData 
    }).then(function (response) { 
    ... 
    }); 
} 
7

ich vor kurzem mit IPFS arbeitete und arbeitete dies. Ein curl Beispiel für IPFS eine Datei hochzuladen sieht wie folgt aus:

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" 

Die Grundidee ist, dass jeder Teil (geteilt durch Zeichenfolge in boundary mit --) hat einen eigenen Header (Content-Type im zweiten Teil, zum Beispiel ist.) Das Objekt FormData verwaltet all dies für Sie, also ist es ein besserer Weg, um unsere Ziele zu erreichen.

Dies führt API so zu holen:

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) 
})