Am'm încercând pentru a POSTA un obiect JSON folosind aduce.
Din ce am înțeles, trebuie să atașați o stringified obiect la corpul de cerere, de exemplu:
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) })
Atunci când se utilizează [jsfiddle's json ecou][2] m-am'd astept sa vad obiect pe care-l'am trimis ({o: 1, b: 2}
) înapoi, dar acest lucru nu se întâmplă - chrome devtools nu't arăta chiar de JSON ca parte a cererii, ceea ce înseamnă că-l's nu a fost trimis.
Cu ES2017 `asincron/așteaptă sprijin, acest lucru este cum să "POST" - un JSON sarcină utilă:
(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);
})();
Poate't folosi ES2017? A se vedea @vp_art's răspunde folosind promisiuni
Întrebarea este însă cere o problemă cauzată de o de mult timp de când chrome fix bug. Original răspunsul urmează.
crom devtools nu't arăta chiar de JSON ca parte a cererii
Aceasta este adevărata problemă aici, și-l's o bug cu chrome devtools, fix în Chrome 46.
Codul funcționează bine - este de a Posta JSON în mod corect, că doar nu poate fi văzut.
nu'd astept sa vad obiect pe care-l'am trimis înapoi
ca's nu funcționează pentru că nu este formatul corect pentru JSfiddle's echo.
De [codul corect][5] este:
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 ) ) })
Pentru efecte acceptarea JSON utile, codul original este corectă
Cred ca problema ta este jsfiddle
poate procesa `form-urlencoded cererea numai.
Dar modul corect de a face cerere json este de a trece corect json
, ca organism:
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));
La motoarele de căutare, am ajuns pe acest subiect pentru non-json postarea datelor cu fetch, așa că aș adăuga acest lucru.
Pentru non-json nu't trebuie să utilizeze formularul de date. Puteți seta pur și simplu "Content-Type" antet pentru application/x-www-form-urlencoded
și de a folosi un șir de caractere:
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'
});
O modalitate alternativă de a construi acel "corp" șir de caractere, mai degrabă, apoi tastați-l cum am făcut-o mai sus, este de a utiliza biblioteci. De exemplu stringify funcția de [
query-string`](https://www.npmjs.com/package/query-string) sau ["qs"] (https://www.npmjs.com/package/qs) pachete. Deci, folosind acest lucru ar arata ca:
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}
});
După ce a petrecut câteva ori, inginerie inversă jsFiddle, încercarea de a genera o sarcină utilă - există un efect.
Vă rugăm să luați la ochi (de îngrijire) pe linie de returnare a răspuns.json();` în cazul în care răspunsul nu este un răspuns - aceasta este promisiunea.
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 > 42Am creat un înveliș subțire în jurul valorii de fetch (), cu multe îmbunătățiri dacă utilizați un pur json REST API:
// 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);
});
Să-l folosească trebuie variabila " api " și 4 metode:
api.get('/todo').then(all => { /* ... */ });
Și într-o "asincron" funcția:
const all = await api.get('/todo');
// ...
Exemplu cu 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');
});
A avut aceeași problemă - nu "corpul" a fost trimis de la un client la un server.
Adăugarea de "Content-Type" antet rezolvat-o pentru mine:
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 => {
...
})
Acest lucru este legat de "Content-Type". Cum s-ar putea să fi observat la alte discuții și răspunsuri la această întrebare unii oameni au fost capabili să rezolve prin setarea Content-Type: 'application/json'
. Din păcate, în cazul meu l-am't de lucru, postarea mea cerere a fost încă gol pe partea de server.
Cu toate acestea, dacă încercați cu jQuery's $.post()
și's de lucru, motivul este, probabil, pentru că de jQuery folosind Content-Type: 'x-www-form-urlencoded' "în loc de" 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'}
})
Răspunsul de sus, nu't de lucru pentru PHP7, pentru că a greșit codare, dar am putea da seama de dreptul de codare cu alte răspunsuri. Acest cod trimite, de asemenea, de autentificare cookie-uri, care probabil vrei ca atunci când se ocupă cu, de exemplu PHP forumuri:
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);
});
}
Ar putea fi util pentru cineva:
Am avut problema asta formdata nu a fost trimis pentru cererea mea
În cazul meu a fost o combinație de următoarele antete care au fost, de asemenea, cauzează problema și greșit Content-Type.
Așa că am fost trimis aceste două antete cu cererea și nu a fost't trimiterea formdata cand am scos antete care a lucrat.
"X-Prototip-Versiune" : "1.6.1", "X-Solicitat-Cu" : "XMLHttpRequest"
De asemenea, ca alte răspunsuri sugerează că antetul Content-Type trebuie să fie corectă.
Pentru cererea mea de a corecta Conținutul-Tip antet a fost:
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
Deci, linia de jos dacă formdata nu este atașat la Cerere, atunci acesta ar putea fi anteturile. Incearca aducerea anteturile la un nivel minim și apoi încercați să adăugați-le unul câte unul pentru a vedea dacă problema este rsolved.
Dacă JSON încărcătura conține tablouri și obiecte imbricate, mi-ar folosi URLSearchParams și jQuery's
param () metodă.
fetch('/somewhere', {
method: 'POST',
body: new URLSearchParams($.param(payload))
})
La server-ul dvs., acesta va arata ca un standard HTML `<formă> "a fi" POST ' ed.
Cred că, nu ne't nevoie de parse JSON obiect într-un șir, dacă serverul de la distanță acceptă json în cerere, trebuie doar să rulați:
const request = await fetch ('/echo/json', {
headers: {
'Content-type': 'application/json'
},
method: 'POST',
body: { a: 1, b: 2 }
});
Cum ar fi curl cerere
curl -v -X POST -H 'Content-Type: application/json' -d '@data.json' '/echo/json'
În cazul în care de la distanță servi nu accepta un fișier json ca organismul, doar trimite 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
});
Cum ar fi curl cerere
curl -v -X POST -H 'Content-type: application/x-www-form-urlencoded' -d '@data.txt' '/echo/form'