Fetch: POST json data

后端 未结 13 1493
小蘑菇
小蘑菇 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 04:18

    If your JSON payload contains arrays and nested objects, I would use URLSearchParams and jQuery's param() method.

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

    To your server, this will look like a standard HTML <form> being POSTed.

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

    You only need to check if response is ok coz the call not returning anything.

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

    This is related to Content-Type. As you might have noticed from other discussions and answers to this question some people were able to solve it by setting Content-Type: 'application/json'. Unfortunately in my case it didn't work, my POST request was still empty on the server side.

    However, if you try with jQuery's $.post() and it's working, the reason is probably because of jQuery using Content-Type: 'x-www-form-urlencoded' instead of 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'}
    })
    
    0 讨论(0)
  • 2020-11-22 04:19

    It might be useful to somebody:

    I was having the issue that formdata was not being sent for my request

    In my case it was a combination of following headers that were also causing the issue and the wrong Content-Type.

    So I was sending these two headers with the request and it wasn't sending the formdata when I removed the headers that worked.

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

    Also as other answers suggest that the Content-Type header needs to be correct.

    For my request the correct Content-Type header was:

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

    So bottom line if your formdata is not being attached to the Request then it could potentially be your headers. Try bringing your headers to a minimum and then try adding them one by one to see if your problem is rsolved.

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

    you can use fill-fetch, which is an extension of fetch. Simply, you can post data as below:

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

    I have created a thin wrapper around fetch() with many improvements if you are using a purely 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);
    });
    

    To use it you have the variable api and 4 methods:

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

    And within an async function:

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

    Example with 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');
    });
    
    0 讨论(0)
提交回复
热议问题