read leer change javascript json fetch-api

javascript - leer - Recuperar: datos POST json



leer json (11)

Estoy tratando de PUBLICAR un objeto JSON usando fetch .

Por lo que puedo entender, necesito adjuntar un objeto en cadena al cuerpo de la solicitud, 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) })

Al usar el json echo de jsfiddle, esperaría ver el objeto que he enviado ( {a: 1, b: 2} ) de regreso, pero esto no sucede: las herramientas de Chrome no muestran el JSON como parte de la solicitud , lo que significa que no se está enviando.


Con el soporte async/await ES2017, así es como POST una carga 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); })();

¿No puedes usar ES2017? Ver la respuesta de @ vp_art usando promesas

Sin embargo, la pregunta es pedir un problema causado por un error de Chrome solucionado hace mucho tiempo.
La respuesta original sigue.

Devtools de Chrome ni siquiera muestra el JSON como parte de la solicitud

Este es el verdadero problema aquí , y es un error con las herramientas de Chrome, solucionado en Chrome 46.

Ese código funciona bien: está PUBLICANDO el JSON correctamente, simplemente no se puede ver.

Esperaría ver el objeto que he enviado de vuelta

eso no funciona porque ese no es el formato correcto para el eco de JSfiddle .

El código correcto 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 puntos finales que aceptan cargas útiles JSON, el código original es correcto


Creo que su problema es que jsfiddle puede procesar solicitudes form-urlencoded .

Pero la forma correcta de hacer una solicitud json es pasar json correcto como cuerpo:

fetch(''https://httpbin.org/post'', { method: ''post'', headers: { ''Accept'': ''application/json, text/plain, */*'', ''Content-Type'': ''application/json'' }, body: JSON.stringify({a: 7, str: ''Some string: &=&''}) }).then(res=>res.json()) .then(res => console.log(res));


Creo que, no necesitamos analizar el objeto JSON en una cadena, si el servidor remoto acepta json en su solicitud, simplemente ejecute:

const request = await fetch (''/echo/json'', { headers: { ''Content-type'': ''application/json'' }, method: ''POST'', body: { a: 1, b: 2 } });

Tal como la solicitud de rizo

curl -v -X POST -H ''Content-Type: application/json'' -d ''@data.json'' ''/echo/json''

En caso de que el servicio remoto no acepte un archivo json como cuerpo, solo envíe un formulario de datos:

const data = new FormData (); data.append (''a'', 1); data.append (''b'', 2); const request = await fetch (''/echo/form'', { headers: { ''Content-type'': ''application/x-www-form-urlencoded'' }, method: ''POST'', body: data });

Tal como la solicitud de rizo

curl -v -X POST -H ''Content-type: application/x-www-form-urlencoded'' -d ''@data.txt'' ''/echo/form''


Desde los motores de búsqueda, terminé en este tema para publicar datos que no son de Json con fetch, así que pensé en agregar esto.

Para los que no son json , no tiene que usar datos de formulario. Simplemente puede configurar el encabezado Content-Type en 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 del body , en lugar de escribirla como hice anteriormente, es usar bibliotecas. Por ejemplo, la función stringify de query-string o paquetes qs . Entonces usar 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, realice ingeniería inversa jsFiddle, tratando de generar carga útil: hay un efecto.

Por favor, observe (cuidado) en la return response.json(); línea. return response.json(); donde la respuesta no es una respuesta, es una 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: http://jsfiddle.net/egxt6cpz/46/ && Firefox> 39 && Chrome> 42


Esto está relacionado con Content-Type . Como habrás notado en otras discusiones y respuestas a esta pregunta, algunas personas pudieron resolverlo configurando Content-Type: ''application/json'' . Desafortunadamente en mi caso no funcionó, mi solicitud POST todavía estaba vacía en el lado del servidor.

Sin embargo, si intenta con jQuery''s $.post() y está funcionando, la razón probablemente se deba a que jQuery usa Content-Type: ''x-www-form-urlencoded'' lugar de application/json .

var headers = new Headers(); headers.append(''Accept'', ''application/json''); // This one is enough for GET requests headers.append(''Content-Type'', ''application/json''); // This one sends body return fetch(''/some/endpoint'', { method: ''POST'', mode: ''same-origin'', credentials: ''include'', redirect: ''follow'', headers: headers, body: JSON.stringify({ name: ''John'', surname: ''Doe'' }), }).then(resp => { ... }).catch(err => { ... })


He creado una envoltura delgada alrededor de fetch () con muchas mejoras si está utilizando una API REST puramente json:

// Small library to improve on fetch() usage const api = function(method, url, data, headers = {}){ return fetch(url, { method: method.toUpperCase(), body: JSON.stringify(data), // send it as stringified json credentials: api.credentials, // to keep the session on the request headers: Object.assign({}, api.headers, headers) // extend the headers }).then(res => res.ok ? res.json() : Promise.reject(res)); }; // Defaults that can be globally overwritten api.credentials = ''include''; api.headers = { ''csrf-token'': window.csrf || '''', // only if globally set, otherwise ignored ''Accept'': ''application/json'', // receive json ''Content-Type'': ''application/json'' // send json }; // Convenient methods [''get'', ''post'', ''put'', ''delete''].forEach(method => { api[method] = api.bind(null, method); });

Para usarlo tienes la variable api y 4 métodos:

api.get(''/todo'').then(all => { /* ... */ });

Y dentro de una función async :

const all = await api.get(''/todo''); // ...

Ejemplo con jQuery:

$(''.like'').on(''click'', async e => { const id = 123; // Get it however it is better suited await api.put(`/like/${id}`, { like: true }); // Whatever: $(e.target).addClass(''active dislike'').removeClass(''like''); });


La respuesta principal no funciona para PHP7, porque tiene una codificación incorrecta, pero podría encontrar la codificación correcta con las otras respuestas. Este código también envía cookies de autenticación, que probablemente desee cuando se trata, por ejemplo, de foros PHP:

julia = function(juliacode) { fetch(''julia.php'', { method: "POST", credentials: "include", // send cookies headers: { ''Accept'': ''application/json, text/plain, */*'', //''Content-Type'': ''application/json'' "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" // otherwise $_POST is empty }, body: "juliacode=" + encodeURIComponent(juliacode) }) .then(function(response) { return response.json(); // .text(); }) .then(function(myJson) { console.log(myJson); }); }


Puede ser útil para alguien:

Estaba teniendo el problema de que los datos de formulario no se enviaban para mi solicitud

En mi caso, fue una combinación de los siguientes encabezados que también estaban causando el problema y el tipo de contenido incorrecto.

Entonces estaba enviando estos dos encabezados con la solicitud y no estaba enviando los datos de formulario cuando eliminé los encabezados que funcionaban.

"X-Prototype-Version" : "1.6.1", "X-Requested-With" : "XMLHttpRequest"

Además, como otras respuestas sugieren que el encabezado Content-Type debe ser correcto.

Para mi solicitud, el encabezado correcto de Content-Type era:

"Content-Type": "application / x-www-form-urlencoded; charset = UTF-8"

En resumen, si sus datos de formulario no se adjuntan a la Solicitud, podrían ser sus encabezados. Intente llevar sus encabezados al mínimo y luego intente agregarlos uno por uno para ver si su problema está resuelto.


Si su carga útil JSON contiene matrices y objetos anidados, usaría URLSearchParams y el método param() jQuery.

fetch(''/somewhere'', { method: ''POST'', body: new URLSearchParams($.param(payload)) })

Para su servidor, esto se verá como un <form> HTML estándar que se está POST .


Tuve el mismo problema: no se envió ningún body de un cliente a un servidor.

Agregar el encabezado Content-Type resolvió para mí:

data = Object.keys(data).map(key => encodeURIComponent(key) + ''='' + encodeURIComponent(data[key])).join(''&'') fetch(''/api/'', { method: ''post'', credentials: "include", body: data, headers: {''Content-Type'': ''application/x-www-form-urlencoded''} })