Estoy intentando enviar un objeto JSON mediante fetch.
Por lo que puedo entender, necesito adjuntar un objeto stringificado al cuerpo de la petición, por ejemplo:
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) })
Cuando uso [jsfiddle's json echo][2] espero ver el objeto que he enviado ({a: 1, b: 2}
) de vuelta, pero esto no ocurre - chrome devtools ni siquiera muestra el JSON como parte de la petición, lo que significa que no está siendo enviado.
Con ES2017 soporte de async/await
, esto es cómo POST
una carga útil JSON:
begin snippet: js hide: false console: true babel: false -->
(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);
})();
¿No puedes usar ES2017? Ver @vp_art's respuesta usando promesas
Sin embargo, la pregunta se refiere a un problema causado por un error de Chrome corregido hace tiempo. La respuesta original es la siguiente.
chrome devtools doesn't incluso mostrar el JSON como parte de la solicitud
Este es el verdadero problema aquí, y es un error de chrome devtools, corregido en Chrome 46.
Ese código funciona bien - está POSTando el JSON correctamente, sólo que no se puede ver.
Espero ver el objeto que he enviado de vuelta.
que'no funciona porque ese no es el formato correcto para el eco de JSfiddle's.
El [código correcto][5] es:
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 ) ) })
Para los endpoints que aceptan cargas útiles JSON, el código original es correcto
De los motores de búsqueda, terminé en este tema para la publicación de datos no json con fetch, así que pensé en añadir esto.
Para non-json no tienes que usar datos de formulario. Puedes simplemente establecer la cabecera Content-Type
a application/x-www-form-urlencoded
y usar una cadena:
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'
});
Una forma alternativa de construir esa cadena body
, en lugar de escribirla como lo hice anteriormente, es utilizar las bibliotecas. Por ejemplo, la función stringify
de los paquetes query-string
o qs
. Así que usando esto se vería así:
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}
});
Después de pasar algunas veces, la ingeniería inversa jsFiddle, tratando de generar la carga útil - hay un efecto.
Por favor, tenga ojo (cuidado) en la línea return response.json();
donde la respuesta no es una respuesta - es promesa.
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