Sto cercando di inviare un oggetto JSON usando fetch.
Da quello che posso capire, ho bisogno di allegare un oggetto stringato al corpo della richiesta, ad es:
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) })
Quando uso [jsfiddle's json echo][2] mi aspetto di vedere l'oggetto che ho inviato ({a: 1, b: 2}
) indietro, ma questo non accade - chrome devtools non mostra nemmeno il JSON come parte della richiesta, il che significa che non viene inviato.
Con ES2017 supporto async/await
, ecco come POST
un payload JSON:
(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);
})();
Non puoi usare ES2017? Vedi @vp_art's risposta usando le promesse
La domanda tuttavia chiede un problema causato da **un bug di chrome risolto da tempo. Segue la risposta originale.
chrome devtools non mostra nemmeno il JSON come parte della richiesta
Questo è il vero problema qui, ed è un bug con chrome devtools, risolto in Chrome 46.
Quel codice funziona bene - sta POSTando il JSON correttamente, solo che non può essere visto.
Mi aspetterei di vedere l'oggetto che ho inviato indietro
che non funziona perché questo non è il formato corretto per JSfiddle's echo.
Il [codice corretto][5] è:
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 ) ) })
Per gli endpoint che accettano payload JSON, il codice originale è corretto
Dai motori di ricerca, sono finito su questo argomento per la pubblicazione di dati non json con fetch, quindi ho pensato di aggiungere questo.
Per non-json non c'è bisogno di usare i dati del modulo. Puoi semplicemente impostare l'intestazione Content-Type
su application/x-www-form-urlencoded
e usare una stringa:
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'
});
Un modo alternativo per costruire la stringa body
, piuttosto che scriverla come ho fatto sopra, è usare le librerie. Per esempio la funzione stringify
dai pacchetti query-string
o qs
. Quindi, usando questo, sarebbe come:
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}
});
Dopo aver speso un po' di tempo, facendo il reverse engineering di jsFiddle, cercando di generare il payload - c'è un effetto.
Si prega di fare attenzione alla linea return response.json();
dove response non è una risposta - è una promessa.
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