Fetch: POST json data

后端 未结 13 1492
小蘑菇
小蘑菇 2020-11-22 03:25

I\'m trying to POST a JSON object using fetch.

From what I can understand, I need to attach a stringified object to the body of the request, e.g.:



        
相关标签:
13条回答
  • 2020-11-22 03:56

    With ES2017 async/await support, this is how to POST a JSON payload:

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

    Can't use ES2017? See @vp_art's answer using promises

    The question however is asking for an issue caused by a long since fixed chrome bug.
    Original answer follows.

    chrome devtools doesn't even show the JSON as part of the request

    This is the real issue here, and it's a bug with chrome devtools, fixed in Chrome 46.

    That code works fine - it is POSTing the JSON correctly, it just cannot be seen.

    I'd expect to see the object I've sent back

    that's not working because that is not the correct format for JSfiddle's echo.

    The correct code is:

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

    For endpoints accepting JSON payloads, the original code is correct

    0 讨论(0)
  • 2020-11-22 04:06

    From search engines, I ended up on this topic for non-json posting data with fetch, so thought I would add this.

    For non-json you don't have to use form data. You can simply set the Content-Type header to application/x-www-form-urlencoded and use a 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: 'foo=bar&blah=1'
    });
    

    An alternative way to build that body string, rather then typing it out as I did above, is to use libraries. For instance the stringify function from query-string or qs packages. So using this it would look like:

    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
    });
    
    0 讨论(0)
  • 2020-11-22 04:06

    After spending some times, reverse engineering jsFiddle, trying to generate payload - there is an effect.

    Please take eye (care) on line return response.json(); where response is not a response - it is 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

    0 讨论(0)
  • 2020-11-22 04:11

    I think your issue is jsfiddle can process form-urlencoded request only.

    But correct way to make json request is pass correct json as a body:

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

    0 讨论(0)
  • 2020-11-22 04:14

    Had the same issue - no body was sent from a client to a server.

    Adding Content-Type header solved it for 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 => {
       ...
    })
    
    0 讨论(0)
  • 2020-11-22 04:17

    I think that, we don't need parse the JSON object into a string, if the remote server accepts json into they request, just run:

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

    Such as the curl request

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

    In case to the remote serve not accept a json file as the body, just send a 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
    });
    

    Such as the curl request

    curl -v -X POST -H 'Content-type: application/x-www-form-urlencoded' -d '@data.txt' '/echo/form'
    
    0 讨论(0)
提交回复
热议问题