Je vais chercher une URL comme ceci:
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)
})
Mon API s'attend à ce que les données soient de multipart/form-data
donc j'utilise content-type
de ce type ... Mais elle me donne une réponse avec le code d'état 400.
Qu'est ce qui ne va pas avec mon code?
Vous définissez le Content-Type
sur multipart/form-data
, mais vous utilisez ensuite JSON.stringify
sur les données du corps, qui renvoie application/json
. Vous avez une incompatibilité de type de contenu.
Vous devrez encoder vos données sous la forme multipart/form-data
au lieu de json
. Habituellement, multipart/form-data
est utilisé lors du téléchargement de fichiers et est un peu plus compliqué que application/x-www-form-urlencoded
(qui est la valeur par défaut pour les formulaires HTML).
La spécification de multipart/form-data
peut être trouvée dans RFC 1867 .
Pour un guide sur la manière de soumettre ce type de données via javascript, voir here .
L'idée de base est d'utiliser l'objet FormData (non pris en charge dans IE <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) {
...
});
}
Pour https://muffinman.io/uploading-files-using-fetch-multipart-form-data/ assurez-vous que pas pour définir l'en-tête Content-Type
. Le navigateur le définira pour vous, y compris le paramètre boundary
.
Je travaillais récemment avec IPFS et ai travaillé sur cela. Un exemple de curl permettant à IPFS de télécharger un fichier ressemble à ceci:
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"
L'idée de base est que chaque partie (divisée par chaîne dans boundary
avec --
) a ses propres en-têtes (Content-Type
dans la deuxième partie, par exemple). Le FormData
object gère tout cela pour vous, c'est donc un meilleur moyen d'atteindre nos objectifs.
Cela se traduit par récupérer l'API comme ceci:
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)
})