Ik'm probeer een JSON object te POST'en met fetch.
Van wat ik kan begrijpen, moet ik een stringified object aan de body van het verzoek hechten, bijv:
fetch("/echo/json/",
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify({a: 1, b: 2})
})
.then(function(res){ console.log(res) })
.catch(function(res){ console.log(res) })
Bij gebruik van [jsfiddle's json echo][2] zou ik'verwachten het object dat ik'heb verzonden ({a: 1, b: 2}
) terug te zien, maar dit gebeurt niet - chrome devtools toont'niet eens de JSON als onderdeel van het verzoek, wat betekent dat het'niet wordt verzonden.
Met ES2017 async/await
ondersteuning, is dit hoe je een JSON payload POST
:
(async () => {
const rawResponse = await fetch('https://httpbin.org/post', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({a: 1, b: 'Textual content'})
});
const content = await rawResponse.json();
console.log(content);
})();
Kan't ES2017 gebruiken? Zie @vp_art's antwoord met behulp van beloften
De vraag is echter vragen naar een probleem veroorzaakt door een allang opgeloste chrome bug. Origineel antwoord volgt.
chrome devtools laat de JSON niet eens zien als onderdeel van het verzoek
Dit is het echte probleem hier, en het'is een bug met chrome devtools, opgelost in Chrome 46.
Die code werkt prima - het POST de JSON correct, het kan alleen niet worden gezien.
Ik'zou verwachten het object te zien dat ik'heb teruggestuurd
dat'werkt niet omdat dat niet het juiste formaat voor JSfiddle's echo is.
De [juiste code][5] is:
var payload = {
a: 1,
b: 2
};
var data = new FormData();
data.append( "json", JSON.stringify( payload ) );
fetch("/echo/json/",
{
method: "POST",
body: data
})
.then(function(res){ return res.json(); })
.then(function(data){ alert( JSON.stringify( data ) ) })
Voor eindpunten die JSON payloads accepteren, de originele code is correct
Via zoekmachines kwam ik op dit topic terecht voor non-json posting data met fetch, dus dacht ik dit toe te voegen.
Voor non-json hoef je geen form data te gebruiken. Je kunt gewoon de Content-Type
header op application/x-www-form-urlencoded
zetten en een string gebruiken:
fetch('url here', {
method: 'POST',
headers: {'Content-Type':'application/x-www-form-urlencoded'}, // this line is important, if this content-type is not set it wont work
body: 'foo=bar&blah=1'
});
Een alternatieve manier om die body
string op te bouwen, in plaats van hem uit te typen zoals ik hierboven deed, is om bibliotheken te gebruiken. Bijvoorbeeld de stringify
functie uit de query-string
of qs
pakketten. Dus als je dit zou gebruiken, zou het er als volgt uitzien:
import queryString from 'query-string';
fetch('url here', {
method: 'POST',
headers: {'Content-Type':'application/x-www-form-urlencoded'}, // this line is important, if this content-type is not set it wont work
body: queryString.stringify({for:'bar', blah:1}
});
Na een tijdje jsFiddle omgekeerd te hebben, om te proberen payload te genereren - is er een effect.
Let op de regel return response.json();
waar respons geen respons is - het is een belofte.
var json = {
json: JSON.stringify({
a: 1,
b: 2
}),
delay: 3
};
fetch('/echo/json/', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: 'json=' + encodeURIComponent(JSON.stringify(json.json)) + '&delay=' + json.delay
})
.then(function (response) {
return response.json();
})
.then(function (result) {
alert(result);
})
.catch (function (error) {
console.log('Request failed', error);
});
jsFiddle:
&& Firefox > 39 && Chrome > 42