Jeg prøver å POST et JSON-objekt ved hjelp av fetch.
Ut fra det jeg kan forstå, må jeg legge ved et stringified-objekt til brødteksten i forespørselen, f.eks:
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) })
Når jeg bruker [jsfiddle's json echo][2] forventer jeg å se objektet jeg har sendt ({a: 1, b: 2}
) tilbake, men dette skjer ikke - chrome devtools viser ikke engang JSON som en del av forespørselen, noe som betyr at den ikke blir sendt.
Med ES2017 async/await
-støtte er dette hvordan du POSTER
en JSON-nyttelast:
(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 du ikke bruke ES2017? Se @vp_art's svar ved hjelp av løfter
Spørsmålet ber imidlertid om et problem forårsaket av en for lengst fikset kromfeil . Opprinnelig svar følger.
chrome devtools viser ikke en gang JSON som en del av forespørselen
Dette er det virkelige problemet her , og det er en feil med chrome devtools, løst i Chrome 46.
Den koden fungerer fint - den sender JSON riktig, den kan bare ikke sees.
Jeg forventer å se objektet jeg' har sendt tilbake
that' s ikke fungerer fordi det ikke er riktig format for JSfiddle' s ekko.
Den [riktige koden][5] er:
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 ) ) })
For endepunkter som godtar JSON-nyttelast, er den opprinnelige koden korrekt.
Fra søkemotorer havnet jeg på dette emnet for ikke-json-postering av data med henting, så tenkte jeg ville legge til dette.
For ikke-json trenger du ikke å bruke skjemadata. Du kan ganske enkelt sette overskriften Content-Type
til application/x-www-form-urlencoded
og bruke en streng:
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'
});
En alternativ måte å bygge den body
-strengen på, i stedet for å skrive den ut som jeg gjorde ovenfor, er å bruke biblioteker. For eksempel stringify
-funksjonen fra query-string
eller qs
pakkene. Så ved å bruke dette ville det se ut som:
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}
});
Etter å ha brukt noen ganger, reverse engineering jsFiddle, prøver å generere nyttelast - det er en effekt.
Vennligst ta øye (forsiktighet) på linje return response.json();
hvor svaret ikke er et svar - det er løfte.
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