Ophalen: POST JSON-gegevens

Ik probeer een JSON-object te POST met fetch.

Voor zover ik kan begrijpen, moet ik een stringified object toevoegen aan de hoofdtekst van het verzoek, bijvoorbeeld:

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

Bij gebruik van jsfiddle’s JSON-echozou ik het object verwachten dat ik heb verzonden ({a: 1, b: 2}) terug, maar dit gebeurt niet – chrome devtools toont de JSON niet eens als onderdeel van het verzoek, wat betekent dat het niet wordt verzonden.


Antwoord 1, autoriteit 100%

Met ES2017 async/await-ondersteuningis dit hoe om een JSON-payload te POST:

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

Antwoord 2, autoriteit 32%

Ik denk dat uw probleem is dat jsfiddlealleen form-urlencoded-verzoeken kan verwerken.

Maar de juiste manier om een json-verzoek in te dienen, is om de juiste jsonals body door te geven:

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

Antwoord 3, autoriteit 12%

Van zoekmachines kwam ik op dit onderwerp terecht voor het posten van gegevens door niet-json met fetch, dus dacht ik dit toe te voegen.

Voor niet-jsonhoeft u geen formuliergegevens te gebruiken. Je kunt eenvoudig de Content-Typeheader instellen op application/x-www-form-urlencodeden een string gebruiken:

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

Een alternatieve manier om die body-string te bouwen, in plaats van hem uit te typen zoals ik hierboven deed, is door bibliotheken te gebruiken. Bijvoorbeeld de functie stringifyvan query-stringof qs-pakketten. Dus als je dit gebruikt, ziet het er als volgt uit:

import queryString from 'query-string'; // import the queryString class
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}) //use the stringify object of the queryString class
});

4, Autoriteit 6%

Na het doorbrengen van sommige tijden, reverse engineering jsfiddle, probeert u payload te genereren – er is een effect.

Neem het oog (zorg) online in return response.json();waar reactie geen reactie is – het is belofte.

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/ & amp; & amp; Firefox & GT; 39 & AMP; & AMP; Chrome & GT; 42


5, Autoriteit 2%

Ik heb een dunne wikkel gecreëerd rond fetch () met veel verbeteringen als u een puur JSON Rest API gebruikt:

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

Om het te gebruiken, hebt u de variabele apien 4 METHODEN:

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

en binnen een asyncfunctie:

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

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

6, Autoriteit 2%

Dit is gerelateerd aan Content-Type. Zoals je misschien hebt opgemerkt van andere discussies en antwoorden op deze vraag, konden sommige mensen het oplossen door Content-Type: 'application/json'te instellen. Helaas werkte het in mijn geval niet, mijn postverzoek was nog steeds leeg aan de serverzijde.

Als u echter probeert met JQuery’s $.post()en het werkt, is de reden waarschijnlijk vanwege jQuery met behulp van Content-Type: 'x-www-form-urlencoded'in plaats van 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'}
})

7

Het bovenste antwoord werkt niet voor PHP7, omdat het een verkeerde codering heeft, maar ik kon het rechtscodering uitzoeken met de andere antwoorden. Deze code verzendt ook authenticatiekoekjes, die u waarschijnlijk wilt als u bij b.v. PHP-forums:

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

Antwoord 8

2021 antwoord: voor het geval je hier belandt op zoek naar hoe je GET en POST Fetch API-verzoeken kunt maken met async/wait of beloften in vergelijking met axios.

Ik gebruik jsonplaceholder nep-API om te demonstreren:

Api GET-verzoek ophalen met async/wait:

        const asyncGetCall = async () => {
            try {
                const response = await fetch('https://jsonplaceholder.typicode.com/posts');
                 const data = await response.json();
                // enter you logic when the fetch is successful
                 console.log(data);
               } catch(error) {
            // enter your logic for when there is an error (ex. error toast)
                  console.log(error)
                 } 
            }
          asyncGetCall()

Api POST-verzoek ophalen met async/wait:

   const asyncPostCall = async () => {
            try {
                const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
                 method: 'POST',
                 headers: {
                   'Content-Type': 'application/json'
                   },
                   body: JSON.stringify({
             // your expected POST request payload goes here
                     title: "My post title",
                     body: "My post content."
                    })
                 });
                 const data = await response.json();
              // enter you logic when the fetch is successful
                 console.log(data);
               } catch(error) {
             // enter your logic for when there is an error (ex. error toast)
                  console.log(error)
                 } 
            }
asyncPostCall()

Vraag aanvragen met behulp van beloftes:

 fetch('https://jsonplaceholder.typicode.com/posts')
  .then(res => res.json())
  .then(data => {
   // enter you logic when the fetch is successful
    console.log(data)
  })
  .catch(error => {
    // enter your logic for when there is an error (ex. error toast)
   console.log(error)
  })

Postverzoek met behulp van beloftes:

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
   body: JSON.stringify({
     // your expected POST request payload goes here
      title: "My post title",
      body: "My post content."
      })
})
  .then(res => res.json())
  .then(data => {
   // enter you logic when the fetch is successful
    console.log(data)
  })
  .catch(error => {
  // enter your logic for when there is an error (ex. error toast)
   console.log(error)
  })  

Vraag aanvragen met Axios:

       const axiosGetCall = async () => {
            try {
              const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
    // enter you logic when the fetch is successful
              console.log(`data: `, data)
            } catch (error) {
    // enter your logic for when there is an error (ex. error toast)
              console.log(`error: `, error)
            }
          }
    axiosGetCall()

POST-verzoek met Axios:

const axiosPostCall = async () => {
    try {
      const { data } = await axios.post('https://jsonplaceholder.typicode.com/posts',  {
      // your expected POST request payload goes here
      title: "My post title",
      body: "My post content."
      })
   // enter you logic when the fetch is successful
      console.log(`data: `, data)
    } catch (error) {
  // enter your logic for when there is an error (ex. error toast)
      console.log(`error: `, error)
    }
  }
axiosPostCall()

Antwoord 9

Ik denk dat we het JSON-object niet in een string hoeven te parseren, als de externe server json accepteert in het verzoek, voer dan gewoon uit:

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

Zoals het krulverzoek

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

In het geval dat de externe server een json-bestand niet accepteert als de body, stuur dan gewoon een 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
});

Zoals het krulverzoek

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

Antwoord 10

Het kan nuttig zijn voor iemand:

Ik had het probleem dat er geen formuliergegevens werden verzonden voor mijn verzoek

In mijn geval was het een combinatie van de volgende headers die ook het probleem veroorzaakten en het verkeerde Content-Type.

Dus ik stuurde deze twee headers met het verzoek en het stuurde niet de formuliergegevens toen ik de headers verwijderde die wel werkten.

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

Ook zoals andere antwoorden suggereren dat de Content-Type header correct moet zijn.

Voor mijn verzoek was de juiste Content-Type header:

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

Dus het komt erop neer dat als uw formuliergegevens niet aan het verzoek worden toegevoegd, dit mogelijk uw headers zijn. Probeer je headers tot een minimum te beperken en probeer ze een voor een toe te voegen om te zien of je probleem is opgelost.


Antwoord 11

Als uw JSON-payload arrays en geneste objecten bevat, zou ik URLSearchParamsen de param()-methode van jQuery gebruiken.

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

Voor uw server ziet dit eruit als een standaard HTML <form>die POSTed is.


Antwoord 12

Je zou het nog beter kunnen doen met wait/async.

De parameters van http-verzoek:

const _url = 'https://jsonplaceholder.typicode.com/posts';
let _body = JSON.stringify({
  title: 'foo',
  body: 'bar',
  userId: 1,
});
  const _headers = {
  'Content-type': 'application/json; charset=UTF-8',
};
const _options = { method: 'POST', headers: _headers, body: _body };

Met schone async/wait-syntaxis:

const response = await fetch(_url, _options);
if (response.status >= 200 && response.status <= 204) {
  let data = await response.json();
  console.log(data);
} else {
  console.log(`something wrong, the server code: ${response.status}`);
}

Met ouderwetse fetch().then().then():

fetch(_url, _options)
  .then((res) => res.json())
  .then((json) => console.log(json));

Antwoord 13

Je hoeft alleen te controleren of het antwoord ok is, want de oproep geeft niets terug.

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((response) => {if(response.ok){alert("the call works ok")}})
.catch (function (error) {
    console.log('Request failed', error);
});    

Antwoord 14

mijn eenvoudige doel is js object ->-> php $_POST

Object.defineProperties(FormData.prototype, { // extend FormData for direct use of js objects
    load: {
       value: function (d) {
                   for (var v in d) {
                      this.append(v, typeof d[v] === 'string' ? d[v] : JSON.stringify(d[v]));
                   }
               }
           }
   })
var F = new FormData;
F.load({A:1,B:2});
fetch('url_target?C=3&D=blabla', {
        method: "POST", 
          body: F
     }).then( response_handler )

15

U kunt vul-fetch , die een uitbreiding van fetch. Eenvoudig, u kunt gegevens plaatsen zoals hieronder:

import { fill } from 'fill-fetch';
const fetcher = fill();
fetcher.config.timeout = 3000;
fetcher.config.maxConcurrence = 10;
fetcher.config.baseURL = 'http://www.github.com';
const res = await fetcher.post('/', { a: 1 }, {
    headers: {
        'bearer': '1234'
    }
});

Other episodes