Poskušam poslati objekt JSON z uporabo fetch.
Iz tega, kar razumem, je razvidno, da moram telesu zahteve priložiti objekt v obliki niza, npr:
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) })
Pri uporabi [jsfiddle's json echo][2] bi pričakoval, da bom videl objekt, ki sem ga poslal (`{a: 1, b: 2}}), vendar se to ne zgodi - chrome devtools sploh ne prikaže JSON kot del zahteve, kar pomeni, da se ne pošlje.
S podporo ES2017 async/await
je to način, kako POSTOVATI
koristni tovor 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);
})();
Ne morete uporabiti ES2017? Glej @vp_art's odgovor z uporabo obljub
Vprašanje pa se nanaša na težavo, ki jo je povzročil davno odpravljen hrošč v Chromu. Izvirni odgovor sledi.
chrome devtools sploh ne prikaže JSON kot del zahteve
To je resnična težava in gre za napako v orodju chrome devtools, ki je bila odpravljena v Chromu 46.
Ta koda deluje pravilno - pravilno pošilja JSON, le videti ga ni mogoče.
Pričakoval bi, da se bo objekt, ki sem ga poslal nazaj, prikazal
to ne deluje, ker to ni pravilna oblika za JSfiddle's echo.
[pravilna koda][5] je:
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 ) ) })
Za končne točke, ki sprejemajo koristni tovor JSON, je izvirna koda pravilna
Iz iskalnikov sem končal na tej temi za ne-json objavljanje podatkov s fetch, zato sem mislil, da bi to dodal.
Za non-json vam ni treba uporabljati podatkov iz obrazca. Lahko preprosto nastavite glavo Content-Type
na application/x-www-form-urlencoded
in uporabite niz:
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'
});
Alternativni način za sestavo tega niza body
, namesto da ga vnesete, kot sem to storil zgoraj, je uporaba knjižnic. Na primer funkcijo stringify
iz paketov query-string
ali qs
. S tem bi bilo videti takole:
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}
});
Po porabi nekaj časa, povratni inženiring jsFiddle, poskuša ustvariti koristni tovor - obstaja učinek.
Bodite pozorni na vrstico return response.json();
, kjer response ni odgovor - je obljuba.
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