Recupero: dati POST json

Sto provando a POSTARE un object JSON usando fetch .

Da quello che posso capire, ho bisogno di albind un object stringa al corpo della richiesta, ad esempio:

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 json jsfiddle echo mi aspetterei di vedere indietro l’object che ho inviato ( {a: 1, b: 2} ), ma questo non accade – chrome devtools non mostra nemmeno il JSON come parte della richiesta , il che significa che non viene inviato.

Con ES2017 async/await supporto , ecco come POSTARE 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); })(); 

Penso che il tuo problema sia che jsfiddle possa elaborare solo la richiesta di form-urlencoded .

Ma il modo corretto per fare la richiesta di json è passare correttamente json come un corpo:

 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)); 

Dai motori di ricerca, sono finito su questo argomento per i dati di pubblicazione non-json con fetch, quindi ho pensato di aggiungere questo.

Per i non-json non devi usare i dati del modulo. Puoi semplicemente impostare l’intestazione Content-Type su application/x-www-form-urlencoded e utilizzare 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 build quella stringa del body , piuttosto che scriverlo come ho fatto sopra, è usare le librerie. Ad esempio la funzione stringify dai pacchetti query-string o qs . Quindi usando questo sembrerebbe:

 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 trascorso alcune volte, il reverse engineering di jsFiddle, cercando di generare un payload, ha un effetto.

Si prega di tenere d’occhio (cura) on line return response.json(); dove la risposta non è una risposta – è una promise.

 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

Ho creato un involucro sottile attorno a fetch () con molti miglioramenti se si utilizza un’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); }); 

Per usarlo si ha la variabile api e 4 metodi:

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

E all’interno di una funzione async :

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

Esempio 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'); }); 

Ho avuto lo stesso problema: nessun body stato inviato da un client a un server.

L’aggiunta dell’intestazione Content-Type ha risolto per me:

 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 => { ... }) 

Questo è legato al tipo di Content-Type . Come avresti potuto notare da altre discussioni e risposte a questa domanda alcune persone sono state in grado di risolverlo impostando Content-Type: 'application/json' . Purtroppo nel mio caso non ha funzionato, la mia richiesta POST era ancora vuota sul lato server.

Tuttavia, se provi con $.post() jQuery e funziona, il motivo è probabilmente dovuto a jQuery che usa Content-Type: 'x-www-form-urlencoded' invece di application/json .

 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'} }) 

Potrebbe essere utile a qualcuno:

Stavo avendo il problema che i dati del form non venivano inviati per la mia richiesta

Nel mio caso si trattava di una combinazione delle seguenti intestazioni che causavano anche il problema e il tipo di contenuto errato.

Quindi stavo inviando queste due intestazioni con la richiesta e non inviavo i formdata quando ho rimosso le intestazioni che funzionavano.

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

Inoltre, come altre risposte suggeriscono che l’intestazione Content-Type deve essere corretta.

Per la mia richiesta l’intestazione Content-Type corretta era:

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

Quindi, se i tuoi dati non sono allegati alla Richiesta, potrebbero potenzialmente essere le tue intestazioni. Prova a ridurre al minimo le intestazioni e poi prova ad aggiungerle una alla volta per vedere se il problema è risolto.

La risposta in alto non funziona con PHP7, perché ha una codifica errata, ma ho potuto capire la giusta codifica con le altre risposte. Questo codice invia anche i cookie di autenticazione, che probabilmente si desiderano quando si gestiscono, ad esempio, i forum 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); }); } 

Penso che, non abbiamo bisogno di analizzare l’object JSON in una stringa, se il server remoto accetta json in loro richiesta, basta eseguire:

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

Come la richiesta di arricciatura

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

Nel caso in cui il servizio remoto non accetti un file json come corpo, basta inviare un dataform:

 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 }); 

Come la richiesta di arricciatura

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